简体   繁体   中英

Moving stylesheets to the document head during PHP execution

I'm trying to come up with a system where visual components like foo or faa would be stored in the /components folder, and each component would be in its folder with that components files, say /foo , and the component files foo.component.css and foo.component.php inside it.

The name.component.php has some HTML and a style <link> inside, referring to the name.component.css. which styles that component. Components are included in page files, such as index.php , which gets its <head> tag from head.php , which is outside the root .

The file hierarchy would look like this:

├──* head.php
└──* /root
   ├──* index.php
   └──* /components
      ├──* /foo
      │  ├── foo.component.css
      │  └── foo.component.php
      └──* /faa
         ├── faa.component.css
         └── faa.component.php

When index.php includes a component, its CSS will be added outside the <head> , which I would like to avoid. Is there a way to move the CSS link to the document <head> during the PHP execution, for example, with a custom function? The CSS needs to be moved from the name.component.php specifically, so manually adding the CSS to the head.php won't do.

File: head.php

<head>
    <!-- Other non-component stylesheets here; -->
    <!-- Component stylesheets would be moved here during PHP execution; -->
</head>
<body>

File: index.php

require_once("../head.php");
require_once("coponents/foo.component.php");

File: foo.component.php

// Can this be moved to the head during execution from this folder?
echo('<link href="/components/foo/foo.component.css" rel="stylesheet">');

// Some HTML elements here...

// Trigger something here that moves the CSS link to the head.php

Could buffering be an option here? Any pointers would be appreciated.

Should your component really define the css with an echo?

Your index.php could insert it, if you followed a naming convention. The problem you'll see is when you have more complexe things to do...

The way I'd do it is to create some sort of manifest for your component. You'd have a class that would list the required css files, javascript files (why not) and template files. Your index.php could easily run through the definition and include at the proper places.

// File foo.manifest.php
class FooComponent implements Component{
    public $stylesheets = ['foo.component.css'];
    public $javascripts= ['foo.component.js'];
    public $dependsOn = []; // You could set dependencies here so other components are loaded if needed.
    public $template = 'foo.component.php';
}

You index would load up the class, and loop through its stylesheets to echo them at the right place.

$components = [new Foo(),new Faa()];
foreach($components as $component){
   foreach($component->stylesheet as $stylesheet){
      echo ('<link href="'.$stylesheet.'" rel="stylesheet">');
   }
}
require_once("../head.php");

foreach($components as $component){
   require_once($component->template); 
}

You'll have to figure out how to play with the paths tough, either your manifest declares them relative to the index.php or you find a way to know the file from where the manifest class comes from so you can make a relative path from it, unfortunately I'm not very good at PHP for this...

What I am doing in the website I am working on now is to have a single head.php file which I bring into the PHP files for the various pages on my site. Sometimes a particular PHP file for one of the pages may require a different JS file or CSS file. So, I have <?= $headEls?> inside the head element in head.php .

Now, inside one of the PHP files for the pages I can assign a value to $headEls which is just a string for any script or link elements that may be required.

One problem is that with the above system you have to assign a value to $headEls inside every PHP file (even if you just make it an empty string) or you get an error trying to access an undefined variable. In order to get round that I put the following line inside head.php before trying to access $headEls : The line is $headEls = isset($headEls)? $headEls: ''; $headEls = isset($headEls)? $headEls: ''; . So now I only have to assign a value to $headEls if I actually have a CSS or JS file(s) I want to bring into it.

I am sure that better systems can be thought of but it does work and I do not want to use a framework which solves all these problems plus ones I have never thought about but involves 1000s of files on my server and my local machine.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM