Jump to content

Changing htaccess RewriteCond to allow access to specific file in otherwise blocked directory to use php variables in css


wwwouter
 Share

Recommended Posts

Some context: I want to use PHP variables in my CSS (more info below) and found a solution on CSS-tricks that looks fairly elegant and somewhat solid to me. It's pretty simple, I created a file style.css.php inside the site/templates/ directory and load that in my page head. In style.css.php is the following:

<?php
header("Content-type: text/css; charset: UTF-8");
header("Charset:utf-8");

if ($homepage->hero_image) {
	echo <<<CSS
	.hero {
		background: url($homepage->hero_image->url) no-repeat;
	}
CSS;
}
?>

Because of the following RewriteCond (line 373) in the htaccess file the server sends a 403 error back when the file is requested:

# Block access to any PHP or markup files in /site/templates/ or /site-*/templates/
RewriteCond %{REQUEST_URI} (^|/)(site|site-[^/]+)/templates($|/|/.*\.(php|html?|tpl|inc))($|/) [NC,OR]

(My htaccess file is @version 3.0 and @htaccessVersion 301)

This is how I thought I could fix that (based on these answers on stack overflow) but it does not work:

# Block access to any PHP or markup files in /site/templates/ or /site-*/templates/
RewriteCond %{REQUEST_URI} (^|/)(site|site-[^/]+)/templates($|/|/((?!style\.css).)*\.(php|html?|tpl|inc))($|/) [NC,OR]

I tested the rule with htacess tester and htaccess check and both worked for me, but on my site I still get a 403 instead of the file.

I'm working on localhost, using MAMP (not sure if that's relevant).

A bit more about what I want to do achieve specifically:
I want to use an image as a background-image for an element, not place it as an image. This image is provided by the user via a field and can therefore change.
I know I can achieve this like this:

echo "<section class='hero' style='background-image: url($page->hero_image->url)'></section>";

But I would prefer a method other than inlining because of scalability and cleanliness. (I admit the extra link in the page head is not ideal either)

 

P.s. this is my first post here, I hope it's submitted in the right forum and my explanation is clear.

Link to comment
Share on other sites

Welcome to the forums!

If you don't want to use inline CSS, would you be happy with including the CSS in the template file's head section? Something along the lines of:

<style>.hero{background: url(<?=$page->hero_image->url?>) no-repeat;}</style>

Or you could build the style line in a separate PHP file and include the file. I may be missing something, but I'm not sure that placing the PHP getting the image URL in a linked CSS file would be more scalable or cleaner than placing it in an included PHP file. And you could avoid having to wrestle with htaccess!

Link to comment
Share on other sites

On 2/27/2021 at 6:23 PM, wwwouter said:

P.s. this is my first post here, I hope it's submitted in the right forum and my explanation is clear.

Looks fine to me 🙂

Hi @wwwouter, welcome to the forums.

To your question about generating a dynamic CSS file via PHP, I would do it like this:

1) create a php file for example called "dyncss.php" and copy it under site/templates/ (look that it starts with a namespace signature "<?php namespace ProcessWire;"

2) in pw admin under setup > templates > addNew create a new template and select dyncss as its template file

3) in your site/config.php create a appropriate content header for css files, according to the advice "To add more content types see contentTypes in /wire/config.php (and add them in /site/config.php)."

// in site/config.php merge our custom types into the existing core ones
$config->contentTypes = array_merge($config->contentTypes,
    array(
        'css' => 'text/css'
    )
);

4) now open the template in backend under setup > templates > dyncss and adjust some settings:
     a) under family tab set "no, may not have children" and  for example "can be used for new pages = one", if you only want to have one unique page of this type
     b) under the files tab disable the compiler, under content type select css, and if you use delayed output with prepend and append files you have to disable this here for this content type
     c) adjust others as you may like or need and save and close the template

5) create a page in your page tree that has this template, give the page a page name that you want to call as url for your dynamic css file for example "mycss"

6) put all your php/css magic into the php file under site/templates and add the URL of your generated page where ever you need it in your generated html


If you later on want to use more than one dynamic css file, you can decide to allow more than one page with that template, or go the root with url-segments and a single page what I would prefer.

But first I hope this can be a good starting point to get you going. If questions arise, come back here into this thread again and ask. 🙂
Happy exploring and coding.

Edited by horst
corrected typos
  • Like 3
Link to comment
Share on other sites

Thank you both! @horst your solution works great for me. Configuring content types is a part of PW I was not yet familiar with.
It's so cool to discover new ways in which PW is such a powerfull and customizable product.

This solves my problem, but I'm still curious why my altered RewriteCond didn't work, if anyone knows the answer to that I'd love to know!

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Zendex
      Hi,
      I am trying to make a site for a studio, and I wanted to set a specific hover effect for my text. I want the background of the text to be lit up in the full height of the nav bar but it doesn't do it. I showed the expected result in the png in the attached files. I will also set the code here below, the top part is a css reset.
       
      HTML:
      <!doctype html>
      <html>
      <head>
      <meta charset="UTF-8">
      <title>Zendex</title>
          <link href="style.css" rel="stylesheet" type="text/css">
          <link rel="preconnect" href="https://fonts.gstatic.com"> 
      <link href="https://fonts.googleapis.com/css2?family=Offside&display=swap" rel="stylesheet">
      </head>
      <body>
          <div id="nav_bar">
              <div id="Zendex">ZENDEX</div>
      <ul>
          <a href="contact.html"><li>CONTACT</li></a>
          <a href="films.html"><li>FILMS</li></a>
          <a href="about.html"><li>ABOUT</li></a>
          <a href="home.html"><li>HOME</li></a>
              </ul>
          </div>
          <div class="main"></div>
      </body>
      </html>
      CSS:
      @charset "UTF-8";
      /* CSS Document */
      html, body, div, span, applet, object, iframe,
      h1, h2, h3, h4, h5, h6, p, blockquote, pre,
      a, abbr, acronym, address, big, cite, code,
      del, dfn, em, img, ins, kbd, q, s, samp,
      small, strike, strong, sub, sup, tt, var,
      b, u, i, center,
      dl, dt, dd, ol, ul, li,
      fieldset, form, label, legend,
      table, caption, tbody, tfoot, thead, tr, th, td,
      article, aside, canvas, details, embed, 
      figure, figcaption, footer, header, hgroup, 
      menu, nav, output, ruby, section, summary,
      time, mark, audio, video {
          margin: 0;
          padding: 0;
          border: 0;
          font-size: 100%;
          font: inherit;
          vertical-align: baseline;
      }
      article, aside, details, figcaption, figure, 
      footer, header, hgroup, menu, nav, section {
          display: block;
      }
      body {
          line-height: 1;
          background-color: #6A6969;
      }
      ol, ul {
          list-style: none;
      }
      blockquote, q {
          quotes: none;
      }
      blockquote:before, blockquote:after,
      q:before, q:after {
          content: '';
          content: none;
      }
      table {
          border-collapse: collapse;
          border-spacing: 0;
      }
      /*-------------------------------------------------------------------------------------------------------------------------------------------------*/
      #nav_bar{
          overflow: hidden;
          position: fixed;
          top: 0;
          width: 100vw;
          height: 125px;
          background-color: #484848;
          border: solid 1px black;
      }
      li{
          font-size: 24px;
          text-shadow: 1px 1px 100px white;
          font-family: 'Offside', cursive;
          float: right;
          margin: 45px 50px 0px 0px;
          height: 125px;
      }
      #Zendex{
          font-size: 24px;
          text-shadow: 1px 1px 100px white;
          font-family: 'Offside', cursive;
          float: left;
          margin: 45px 0px 0px 100px;
          color: azure;
      }
      #home{
          
      }
      #about{
          
      }
      #films{
          
      }
      #contact{
          
      }
      ul{
          margin: 0px 50px 0px 0px;
          color: azure;
          height: 125px;
      }
      a:link{
          color: white;
      }
      li:hover{
          height: 125px;
          background-color: #6A6969;
          color: white;
      }
       

    • By milo695
      Hello,
      I've added a class in ProcessPageEditLink but when I call it from Editor (attributes > class) nothing happens.
      Also, I've created the class in my custom.css, is there any other css file this class needs to be in?
      thanks
    • By theoretic
      Hi there! And thanks for Processwire!
      I've got an interesting case concerning access to current user page. It appears that PW somehow limits access to the frontend page of current user.
      I'm speaking about a specific PW configuration. We have two kind of users: 'regular' users with native user template and member users with specific member template and specific members parent page (by the way, it's so cool that PW allows to use custom user templates and custom parent for certain user pages!). So a member with name Joe has a page with member template and url like /members/joe .
      The members template has some access limitations: only member users can see pages with member template. It works like a charm in most situations. For example, user Bill (who has member template and is logged in) can browse a page with url /members/ann which also is a member page with member template.
      And now, meet the glitch! The above-mentioned Bill cannot get to his own page /members/bill ! PW generates 404 page instead.
      I see no reason for this behavior. From my point of view any member should have access to any member page in this situation. What am i doing wrong? Any advice is welcome!
    • By RDC
      Is the right way to get Processwire to skip a folder (ie not process it as its running a different CMS) to put
      RewriteCond %{REQUEST_URI} !^/shop/.*$
      just before 
      RewriteRule ^(.*)$ index.php?it=$1 [L,QSA]
      in .htaccess?
    • By Spiria
      I am writing here instead of the ProCache forum because I have the impression that several nginx experts could solve this. In its new version, Procache proposes new .htaccess rules that are difficult to translate into nginx rules. We currently have a problem with the trailing slash of URLs which gives us a bad score in SEO analysis tools such as semrush.com. 
      Indeed, a canonical URL is either without or with "/", but cannot be served by both options. Although ProcessWire without ProCache respects this rule, ProCache has no difficulty serving both, which is considered an SEO optimisation fault. I believe that ProCache version 2 solves this problem with these new rules, but I can't understand the following. Does anyone have any idea how to translate this into a nginx rule?
      Attached also the whole proposed .htaccess for ProcessWire.
      # PROCACHE v2/31885be14d6cfb4b2b0d3e533260bded -------------------------------------------------- RewriteCond %{REQUEST_METHOD} !=POST RewriteCond %{QUERY_STRING} !.*=.* RewriteRule ^.*/$ - [E=pwpcstep:pour,E=pwpcname:index] RewriteCond %{ENV:pwpcstep} "=pour" RewriteCond %{HTTP_COOKIE} !^.*(wire_challenge|wires_challenge).*$ RewriteRule ^.*/$ - [E=pwpcstep:stir,E=pwpcpath:%{DOCUMENT_ROOT}/site/assets/ProCache-00478359c5e65dbada1075bfbd4] RewriteCond %{ENV:pwpcstep} "=stir" RewriteCond %{ENV:pwpcpath}/$0/%{ENV:pwpcname}.html -f RewriteRule ^.*$ - [E=pwpcstep:drink,E=pwpcfile:$0/%{ENV:pwpcname}.html] RewriteCond %{ENV:pwpcstep} "=drink" RewriteRule ^(.*) %{ENV:pwpcpath}/%{ENV:pwpcfile} [L] <ifModule mod_headers.c> Header set X-PWPC "ProCache" env=pwpcstep Header set X-Powered-By "ProcessWire CMS, ProCache" env=pwpcstep </ifModule> RewriteCond %{REQUEST_URI} "^/~?[-_.a-zA-Z0-9/]*$" # /PROCACHE -------------------------------------------------------------------------------------  
      .htaccess-procache
×
×
  • Create New...