PHP: Twig: Relative paths for images? - php

Wondering if there is a way to use paths relative to the template storage location in the Twig templating engine.
The scenario is as follows:
I have a Typo3 website where my application resides in fileadmin/myApplication. I am using Twig as a template engine to render multilingual content that is loaded dynamically from JSON files. Some of my template files contain paths to images that, given the nature of Typo3, need to have a src-path of fileadmin/myApplication/img/...
Now, if I want to test a new version of my application, I want to be able to create a directory fileadmin/myApplication2.0 without having to change the paths to my images inside the template files.
There are templating engines (e.g. raintpl, see this link) that translate relative paths to server file paths. Is there an easy way of achieving the same effect in Twig?
e.g.
templates/template.html
img/logo.png
outputs
<img src="fileadmin/myApplication2.0/img/logo.png">
This is how rain.tpl does it:
WYSIWYG - Path replace
This cool feature allows designers to create templates as regular HTML with images and styles with relative paths, RainTPL replaces automatically these paths with the correct server paths.
Absolute paths and paths ending with # will be not changed.
<link href="style.css" type="text/css" rel="stylesheet">
<img src="img/logo.gif">
Output html:
<link href="tpl/style.css" type="text/css" rel="stylesheet">
<img src="tpl/img/logo.gif">
Note: if you set raintpl::$base_url, RainTPL will replace the path with raintpl::$base_url.

The path in the src attribute is a relative URL, not a relative file path to the file system on your server, how you organize your files inside your directories.
The relative URL will be resolved to the base URL of the document the template will be part of / present in. So you can use relative URLs, but you need to know to what they relate to to have them properly working.
In your case a quick solution might be to use
<img src="/img/logo.png">
If your website resides in the web-root.
Another way is to have a template function that takes care to build the (relative) URL according to the requested URL path. Another approach is to hard-encode a <base> href Docs in the overall template.
Another alternative is that you get the output of the rendered templates, parse the links and make them suit.
But the important part is that you need to know about the requested URL path in specific and how your template (blocks) are being used.

With absolute path as Joseph said:
<img src="/img/logo.png">
you can see the images only if your website is on a root url as
http://localhost/
it won't work on
http://localhost/myApp/
so in this case you'll need to create an host for it
http://myApp/
A template is WYSIWYG when you can see how it looks in your browser or in your html editor, so basically any templates that use relative paths.
RainTPL had the awesome idea to replace automatically the relative paths of the templates with the correct server path (relative or absolute), so you can see immediately how your template looks.
Another very good way to use WYSIWYG templates is the <base href="http://localhost/myApp/"> tag, which enables you to use relative paths. Only problem is the cross browsing and the Javascript because is not very clear if works the same in all of them.

<img src="{{ asset('img/my_image.gif') }}" alt="something" />
The asset path will resolve to the /web directory. In my example the full project path for the image would be:
Project/web/img/my_image.gif
You'll need to be using the .twig extension to use this method.

Related

php script includes html in different directory

I have a form handler which is written in PHP and resides in a different directory than the html files. When the handler runs, it needs to include one of the html files. The html files have relative hrefs in them, which break because the page was served from the PHP directory, not the html directory.
For example, index.html contains
<link rel="stylesheet" type="text/css" href="css/site_global.css?4013920463"/>
These links are produced by Adobe Muse and expect that "css" is a subdirectory under the location of the html files and that the page was served from the html directory. Again, since I'm serving the page from the PHP directory, the relative links break.
Short of putting in absolute paths for the hrefs, is there any other technique I should consider? I really don't want to put in absolute paths because they will break for other reasons.
Ideally, I'd like to use some sort of method that allows me to set the "working path" in the browser - so that I can tell it to fetch hrefs from the right place.
Relative paths in a browser are computed based on the current page path (see here). If you are looking at http://foo.bar/one/page.html , the site_global.css path will be http://foo.bar/one/css/site_global.css .
If I understood your question, you can use the element to set a base URL for all the relative links in the page.
See here: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
try $_SERVER['DOCUMENT_ROOT'], gives the path to your base directory with current working dir
or
try echo realpath(dirname(FILE));

Dynamic path to CSS & Javascript folders

In a php project I have created a template for Website Header & included a javascript & css menu in it.
Paths for the js & css files for menu are referenced in Header Template so I do not need to include those in every page.
When I include the header template to content pages which are in different levels in folder hierachy, path to js & css file change & does not load. How to overcome this & reference js & css files in a dynamic way?
Use URIs relative to the server root.
i.e. which start with a / character.
You can easily change this by using absolute links in your header template. Just give them an absolute URI like so:
<link rel="stylesheet" href="http://example.com/path/to/style.css" type="text/css" media="screen" />
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Absolute URIs will prevent that you need to deal with the resolving of relative URIs to the documents own base URI.
If you dislike to hard-encode the name of your site, you can make use of server variables (take a look into $_SERVER), resolve the base URI to the document of the request and adopt the path to the CSS/JS files on the fly.
I recommend to not hard-encode personally, however this is less trivial to implement and depends on server configuration, your site's layout and has security implications as well.

Missing CSS file and images after URL rewrite

I'm trying to make user friendly URL using mode rewrite.
My problem is, that after giving category like 'name' to my URL, when I call the page using new URL, it can't load the CSS file or images.
I have a link like:
localhost/mywebsite/project?id=22
New link is something like
localhost/mywebsite/project/22/myproject.project
htaccess code:
RewriteRule ^project/([0-9]*)/.*\.project$ /project.php?project=$1 [L]
(it might not be 100% right but I don't have access to my code right now so I just wrote this and it works fine on the original source)
My root directory is localhost/mywebsite/
and my CSS file is in css/style.css
localhost/mywebsite/css/style.css
my htaccess
localhost/mywebsite/.htaccess
and my project.php file is in
localhost/mywebsite/project.php
So in the project page I have access to CSS file by using relative path,
<link href="css/style.css" rel="stylesheet" type="text/css" />
but when I use rewritten URL page can't find the CSS file.
I can't use absolute path with domain name because I don't have domain yet! and it can be anything.
one way is to use relative path to domain as suggested on the similar questions
localhost/mywebsite/project.php
and when i run my script localy my root directory is
localhost
so css link should look like
href="mywebsite/css/style.css"
but when i go live i should change all links to probably something like
href="/css/style.css"
this seems like lots of work
For your local version add
<base href="//localhost/mywebsite" />
to the head section
and for your live versions change it to
<base href="//your.domain.here" />
reference at http://www.w3.org/TR/html4/struct/links.html#h-12.4
you have to define the base path or the server view path in the connection.php and whenever u want that path, make that global. then that variable will b called and the css or images will take the whole path.
for example
$SVP="http://www.example.com/"
global $SVP;
echo $SVP;
so
Insert an image into the same file with the same relative path as the css href link, load the page in a browser, right-click the image in internet explorer, click properties and you should see where the relative path actually points to.

PHP: Defining relative paths compatible with HTML Tags

Consider the following directory structure:
ROOT
------ images
............... logo.png
------ includes
............... vars.php
------ layout
............... content.php
------ index.php
How do I define a path constant for logo.png in vars.php that is accessible in both index.php and content.php? Should be compatible with HTML Tags as a relative path.
<img src="<?php echo IMAGE_PATH; ?>">
which should be parsed as
<img src="images/logo.png"> <!-- if used in index.php -->
and
<img src="../images/logo.png"> <!-- if used in content.php -->
New Question (EDIT): Does root-relative path work when including php files using include / require methods?
Try setting the <base> tag in the <head> section of your code.
All your images, css, and js files will use this instead of the url in the address bar.
Info on base
Absolute url or root paths will give you the least amount of headaces. Trust me, when the system grows you'll regret that setup.
It is a perfectly legal way to reference things. (as you ask in the comments)
If you're worried about setups between domains, just create a config variable with the absolute path to the domain / directory / etc
You can use "root-relative" paths. Simply link to everything with a forward slash at the beginning, i.e.
<img src="/images/logo.png">
This will resolve to http://yoursite.com/images/logo.png from every page on yoursite.com.
simply specify all paths as relative to the root
<img src="/images/logo.png"> <!-- will work anywhere -->
I'd suggest, primarily, that you use root-relative paths. This is only to reduce the complications of moving your site to another host, and also it allows for consistent paths (rather than using an if() condition to test from where the script's being run).
But otherwise, your suggestion would be fine.
I would use something like an application base URL:
define('APP_URL', 'http://example.com/path/to/app');
echo '<img src="'.APP_URL.IMAGE_PATH.'">';
Or to have it more convenient, write a function that resolves your relative URL to an absolute URL.

How to keep a website with url routing directory independent

I'm developing a PHP website that uses url routing. I'd like the site to be directory independent, so that it could be moved from http://site.example.com/ to http://example.com/site/ without having to change every path in the HTML. The problem comes up when I'm linking to files which are not subject to routing, like css files, images and so on.
For example, let's assume that the view for the action index of the controller welcome contains the image img/banner.jpg. If the page is requested with the url http://site.example.com/welcome, the browser will request the image as http://site.example.com/img/banner.jpg, which is perfectly fine. But if the page is requested with the url http://site.example.com/welcome/index, the browser will think that welcome is a directory and will try to fetch the image as http://site.example.com/welcome/img/banner.jpg, which is obviously wrong.
I've already considered some options, but they all seem imperfect to me:
Use url rewriting to redirect requests from (*.css|*.js|...) or (css/*|js/*|...) to the right path.
Problems: Every extension would have to be named in the rewrite rules. If someone would add a new filetype (e.g. an mp3 file), it wouldn't be rewritten.
Prepend the base path to each relative path with a php function. For example:
<img src="<?php echo url::base(); ?>img/banner.jpg" />
Problems: Looks messy; css- and js-files containing paths would have to be processed by PHP.
So, how do you keep a website directory independent? Is there a better/cleaner way than the ones I came up with?
You could put in the head
<base href="<?php echo url::base(); ?>" />
This will mean the browser will request any non-absolute URLs relative to that path. However I am not sure how this would affect URLs embedded in CSS files etc. This does not affect paths defined in CSS files. (thanks mooware)
The <base> thing will work but you need to remember it's going to affect your <a> tags too. Consider this example.:
<!-- this page is http://oursite.com/index.html -->
<html>
<head>
<base href="http://static.oursite.com/" />
</head>
<body>
<img src="logo.gif" alt="this is http://static.oursite.com/logo.gif" />
this links to http://static.oursite.com/login which is not what we wanted. we wanted http://oursite.com/login
</body>
</html>
If you use a PHP function call for creating your links, that won't be a problem as you can just make sure it spits out absolute URL. But if you (or your designers) hand-code the <a> tags then you're stuck with the same problem again, just now with <a> instead of <img>.
EDIT: I should add the above paragraph is assuming you serve images from a different host name like we do. If you don't then obviously that won't be a problem.
tomhaigh has a good point, and would be worthwhile to investigate it further.
According to MSDN, the base tag works for all external sources, including style sheets, images, etc.
Perhaps I'm missing something, but can't you just do what I (and I thought everybody else) do/es? Namely put all your images, css, javascripts, etc in a common directory i.e.:
/inc/images/
/inc/css/
/inc/javascript/
etc
And then reference them with base-relative URLs, i.e.:
<img src="/inc/images/foo.jpg" />
etc
?

Categories