Passing extra scripts from view to header - php

So I'm basically trying to pass the <link> and <script> tags into my original header file from a modules view file (which is displayed in the body of the page). How can I pass variables that include these references?
Currently I have just put extra <head></head> tags into my module's view, but it just feels messy and dodgy to do so, as that means the head tags are used up the top of the page, and also mid-way down.
Edit: Didn't realise that stack overflow edited out my tags that are crucial to this question! Sorry guys!

It sounds like you are really in need of a Template setup for CodeIgniter. Here are links to some of my favorites:
http://williamsconcepts.com/ci/codeigniter/libraries/template/reference.html
http://philsturgeon.co.uk/demos/codeigniter-template/user_guide/
And my personal favorite for simplicity:
http://maestric.com/doc/php/codeigniter_template
EDIT:
Per #Sneaksta's question, here is how I add css scripts to my template:
In my master template I have this code:
<?php if (!empty($cssFiles)): ?>
<?php foreach ($cssFiles as $styleSheet): ?>
<link rel="stylesheet" media="screen" href="<?= base_url(); ?>styles/<?= $styleSheet; ?>" />
<?php endforeach; ?>
<?php endif; ?>
Then in my controllers that might need to load different CSS files per function I do this:
$cssFiles = array('style1.css', 'style2.css', 'style3.css');
$this->template->set('cssFiles', $cssFiles);

Sneaksta,
I think I understand what you are asking about, but I am not 100% sure because you don't have any code examples posted.
So I will give you an example of how you can have a "telescoping" View that allows you to modularly load different style tags inside the head tags.
As Damien Pirsy mentioned, Views are buffered, which means that CI makes a special output buffer and will concatenate a series of View objects together, and then output the final buffer content as a finished web page.
My example below is built on this sort of chain of thinking:
End User
(calls) --> Page Controller, which then:
(calls & passes params) --> Base View
(calls multiple fragment views) --> Fragment View +
--> Fragment View +
--> Fragment View = Final Cumulative Page --> (sent back as output ) --> End User
First make the "base View", which we will call "base.php" for reference sake:
<!doctype html>
<html>
<head>
<!-- Base View -->
<?php
//This "if" + "isset()" statement is important,
// because if you forget to pass the variable in the controller
// CI will throw an error.
// Also important: the name of variable ($style) MUST match the
// the name of the associative element in the controller! (See
// remarks below on handling this in the controller)
if(isset($style))
{
//Loading views is like a telescoping effect:
//A view may load other views into itself recursively
$this->load->view($style);
}
else
{
//This echo statement will show a comment in
// source code if an error occurred during loading a view
echo "<!-- Style not found -->");
}
?>
</head>
<body>
<!-- Page Content Here -->
</body>
</html>
Next you create the Style View (note: the following code fragment would be in a separate file all by itself) which we will call "style1.php", and must located with your other views in order for CI to find it, e.g. inside the "application/views" folder. This lets you swap out an inline style block declared in the header by just changing which style view is loaded:
<style type="text/css">
/*Style 1:*/
/*Just do something simple and obvious, i.e. turn text red*/
body { color: red; }
</style>
Next you create the alternate Style View (note: the following code fragment would be in a separate file all by itself) which we will call "style2.php", and must located with your other views in order for CI to find it, e.g. inside the "application/views" folder. This lets you swap out an inline style block declared in the header by just changing which style view is loaded:
<style type="text/css">
/*Style 2:*/
/*Just do something simple and obvious, i.e. turn text blue*/
body { color: blue; }
</style>
Now inside of our controller "example.php" we tell base.php to load the style1.php file into its header. We do this by passing the file name as a parameter when we load the base.php view, by passing the file name as an element of an associative array, code igniter will parse that parameter array and create a variable with the same name as the associative element, and make that variable available to you inside the base.php view:
<?php
class Example extends CI_Controller
{
//Constructor
function __construct(){ parent::__construct(); }
//Base View request handler
function baseview()
{
//Note: Make an array, be certain to name the element
// the same as what will be expected inside base.php
$params = array("style" => "style1.php");
//Switching to load a different style is now easy
// just comment out the line above, and uncomment the line below:
//$params = array("style" => "style2.php");
//Pass the parameters array into the CI load view method:
$this->load->view("base.php", $params);
}
}
?>
The cumulative result should be the modular ability to switch the style tags inside the page header, by just specifying which "style view" to load (you could even build a model that retrieves which "style views" to load from a database table). Obviously this approach has certain processing overhead constraints inside of a web browser, as you are constructing actual inline HTML source code, rather than linking to a CSS file through a link tag. This means that the browser will not cache the css content for each page load, but will have to download it on each subsequent request.

Related

How to Update CSS Property in external style sheet via Laravel?

I am working on a project where i am allowing the user to change theme settings i.e colors, design etc from Admin Panel. I want the user to just enter the color hex code and that will change the linked properties in the view. What i tried to do is
In the view:
<style>
button.submitform:hover, button.submitform:focus{
background: {{ $customizer->global_lite_colorcode}} !important;
}
</style>
This solution work perfect but it has to be inline or in the html file, but i want to use externel css file.And this style i.e button.submitform lives in external css file called main.css . I want the laravel variable to change that property in there. How can i do this ?
I don't think that your css file main.css can parse notation of Laravel {{}}. Of course, if you must style pseudo classes like hover or focus, I have an idea about this, I think you can set a fixed style firstly:
button.submitform__red:hover, button.submitform__red:focus{
background: red !important;
}
And dynamically bind style with {{}} like this:
<button>
<div class="submitform__{{$customizer->global_lite_colorcode}}" />
</button>
js way:
document.querySelectorAll('.submitform__{{$customizer->global_lite_colorcode}}')[0].style['background'] = '{{$customizer->global_lite_colorcode}}';
Since you are dealing with a User (who is probably logged-in), you can very easily create CSS Styles based on the User-id and then load the style Dynamically in the view based on which user is logged-in.
STEP 1: USING USER ID TO CREATE A CSS FILE
<?php
// THIS IS AN ACTION IN YOUR CONTROLLER THAT HANDLES THE PROCESSING OF THE
// USER-SETTINGS FORM...
public function saveUserSetting(Request $request){
// OBTAIN THE $userID YOUR WAY...
$userDataPath = __DIR__ . "/../../../public/css/user_data";
// BUILD THE CSS TO BE ADDED TO USERS CUSTOM CSS FILE
// BASED ON HIS SETTINGS...
// $customizer = //<== GET THE $customizer OBJECT
$css = "button.submitform:hover, button.submitform:focus\{\n";
$css .= "background: " . $customizer->global_‌​lite_colorcode . " !important;\n";
$css .= "\}\n"
// IF USER-SPECIFIC CSS FILE DOES NOT EXIST, WE CREATE IT,
// OTHERWISE WE JUST GET ITS CONTENT AND APPEND NEW STYLES TO IT..
if(!file_exists($userDataPath . "/user_{$userID}.css")){
file_put_contents($userDataPath . "/user_{$userID}.css", $css);
}else{
$data = file_get_contents($userDataPath . "/user_{$userID}.css");
if(!stristr($data, $css) ){$data.= $css;}
file_put_contents($userDataPath . "/user_{$userID}.css", $data);
}
// DO OTHER THINGS...
}
Then on the View, make sure you have created a section called "stylesheets" (for example) in your Master-File (That is; if you are using Template inheritance). Your Main Layout File would contain something like below within the < head > section.
#yield("stylesheets")
Then on the actual View File, you can dynamically add the User's Custom Style-Sheet based on the ID of the logged-in User like so:
#extends('layouts.app')
#section('stylesheets')
<link type="text/css" rel="stylesheet" media="all" href="{{ URL::asset('css/bootstrap.min.css') }}" />
<!-- THIS WILL LOAD ONLY THE USER'S CUSTOM CSS -->
<link type="text/css" rel="stylesheet" media="all" href="{{ URL::asset('css/user_data/user_' . $userID . ".css") }}" />
#endsection
However; it is important to note that in this approach, the data has to first be saved and written to File before you can see any changes... you wouldn't have an instant response of seeing your style applied immediately. If you need such Functionality, you may consider integrating Javascript.
Another way would be to gather all the Front-End Settings that the User specified in the Form, and store them as part of the users Table like under the column_name settings in either serialized or json_encoded format. This means that, once you fetch the Logged-in User Information, you can generate a CSS using the information stored in the settings....
This for sure can be done in an external file, but it won't be an external .css file; it will be a .blade.php file that contains any css styling, similar to the way you're doing it above. The issue is that since the property global_lite_colorcode is attached to a php variable $customizer, it cannot be parsed in a plain .css file.
On your view file, include a <style> tag the same way you are currently doing, and use the #include() blade command to pull in an external php file:
<style>
#include("views.custom.themes")
</style>
Specify a valid path to a .blade.php file using . notation, and in that file, include your "pseudo-inline" css:
button.submitform:hover, button.submitform:focus {
background: {{ $customizer->global_lite_colorcode}} !important;
}
<!-- Any other style tags that rely on php variables -->
As long as $customizer is accessible in the view file that calls the #include function, the code in the included file can also access it.
This is a bit of workaround to using an external .css file, but should work for your needs.

How to load an html snippet into page without changing pages

I'm new to PHP (3 days) and I understand the basic concept of using includes for creating high level templates. I'd like to further utilize this tool to load more granular content, but I'm not sure how to approach this. The html below is an example of a page template put together with php includes. If you reference this html, let's say I have a widget on the page contained here: <?php include('include/WIDGET.php'); ?>. In the simplest of scenarios, there would be a link above the widget that reads "Widget 2". On click of this link, I would want the WIDGET.php content to be replaced with widget2.php. How can I manipulate the include to load widget2.php?
HTML
<!-- File: index.php -->
<html>
<head>
<?php include('include/head.php');?>
<title><?php echo $siteName;?></title>
</head>
<body>
<?php include('include/header.php'); ?>
<!-- CONTENT -->
<?php include('include/WIDGET.php'); ?>
<?php include('include/main-content.php'); ?>
<!-- CONTENT END -->
<?php include('include/footer.php'); ?>
</body>
</html>
To change what file(s) is included, you would need to provide some sort of parameter to the page, that can conditionally include the correct widget.
For example, including it in URL query string, such as:
http://yoursite/index.php?content=widget2
Then, in your PHP file, you can get this value:
if (isset($_GET['content']) && !empty($_GET['content'])) {
$widget = $_GET['content'];
} else {
$widget = 'widget';
}
And include it in your HTML:
[...]
<!-- CONTENT -->
<?php include('include/' . $widget . '.php'); ?>
[...]
This is just to give you an example of the logic involved, but I wouldn't use the code as I've provided it as it is incredibly insecure, and doesn't check the existence of files, etc.
I know you're just getting started, and it's a lot to take in at once, but you might want to consider using a PHP framework such as Zend or Symfony, or CakePHP to take advantage of some routing and templating solutions that have already been set up for you.

Render additional html at the beginning or end of action view

I have Zend Framework MVC application with module structure like that above:
/application
/layouts
/sripts
/layout.phtml
/modules
/default
/controllers
/IndexController.php
/OtherController.php
/views
/scripts
/index
/index.phtml
/second.phtml
/third.phtml
/fourth.phtml
/other
/index.phtml
/second.phtml
/third.phtml
/fourth.phtml
In my layout.phtml i have a line
<div id="main">
<?= $this->layout()->content ?>
</div>
I want to wrap rendered action views in every action of IndexController and OtherController, except fourth, with some code, like <div id='top'></div> at the beggining, and <div id='bottom'></div> at the end of rendered action view.
I don't want to do it manually in every action view *.phtml file. There are too many in real application, besides code looks messy with that solution.
How to do it?
In a layout file, you can echo a layout variable. This is usually where we put the html rendered by an action. You can append the rendering from several actions into a single layout variable, and they will be displayed in LIFO order. Here is how that variable is inserted into the layout file:
<?php echo $this->layout()->myLayoutVariable; ?>
You can also set up a placeholder variable inside your layout file:
<?php echo $this->placeholder('myPlaceholderVariable'); ?>
In one of your view files, you can then provide the html content for this placeholder variable:
<?php
$this->placeholder('myPlaceholderVariable')->append('<p>HTML GOES HERE</p>');
?>
If you don't set any value for the placeholder variable, nothing will be rendered in the layout file. But if you do set a value for that placeholder variable, it will be inserted into the html.
You could set a different layout only for IndexController and OtherController : in the init() method of each controller, you can add the following:
Zend_Layout::getMvcInstance()->setLayout('some other layout');
Try this:
$(document).ready(function(){
$("#main").before(//insert header html here);
$("#main").after(//insert footer html here);
});
I'm not sure what you mean by the fourth, but if you want to target a specific controller/action you could grab the window.location.href and make your function dependent on a specific URL you want to look for.
Hope that helps.

CakePHP how to addScript() from inside element?

I have a navigation menu inside a CakePHP element file (views/elements/nav_default.ctp).
The file is included inside another element that is the header (views/elements/header_default.ctp) which is then included in the layout file (views/layouts/default.ctp).
I am trying to tell Cake to load a js file (webroot/js/mega_drop.js) from within the nav element like so:
<?php
$this->addScript('mega_drop');
?>
It does not get included. I looked at the documentation for addScript which just says:
Adds content to the internal scripts
buffer. This buffer is made available
in the layout as $scripts_for_layout.
This method is helpful when creating
helpers that need to add javascript or
css directly to the layout. Keep in
mind that scripts added from the
layout, or elements in the layout will
not be added to $scripts_for_layout.
This method is most often used from
inside helpers, like the Javascript
and Html Helpers.
The key part:
Keep in mind that scripts added from the layout, or elements in the layout will not be added to $scripts_for_layout.
So how do I do it then?
I guess I could add a <script src="/js/mega_drop.js"></script> to the default.ctp layout. That doesn't feel right though as it would tightly tie the layout and the element together.
Whats the CakePHP best practice way to do this?
addScript() does not load a file; it adds actual code to the $scripts_for_layout variable. The idea being that the layout is a good, common place to load your JavaScript files and code. That way you can output all the code in one location - in the head block or at the end - either way it's together. So if you are in a situation where you've got JavaScript code in the view, rather than output it inline, you can pass it up to the layout.
The best way to load a script file is with the HTML Helper- echo $this->Html->script("script or array('of', 'scripts')"); With that in mind, you could $this->set('scripts', 'mega_drop'); in the element and then call the Html Helper with that $scripts variable from the layout.
The problem with that: it won't work if your nav_default.ctp is called from the layout. $this->set() works inside of a view (or an element called from a view) because the View is rendered before the Layout. If you are calling your element from the layout, then it is too late to be setting viewVars for use in the layout. The best thing to do is set() the scripts variable from the Controller and use a if(isset($scripts)) { echo $this->Html->script($scripts); } in the layout.
Correct and valid 1.3.x CakePHP 2.0 Dev is from example.ctp file:
$this->addScript($this->Javascript->link('tab_enabler'));
$this->addScript($this->Html->css('jquery.tabs'));
This is an example of how to properly include CSS and JS files from the view and adding in the variable $scripts_for_layout to not generate validation error with the W3C as it is not correct to add the link to a css file in <BODY></BODY>
try
$this->Html->script('mega_drop', $inline=false);
in your element without the echo.
The Second parameter says to add it to the $scripts_for_layout variable.
You should be able to do this in your element, so that the javascript is only included when the element is.

use common template for all pages of website

ok, the title did not make much sense but this is what i am planning to do. I have designed a template for my website, with head body and div for specific stuff and everything. The website consists of header file, footer file, right-side column, header dropdown menu and a main body which would be present beneath the header dropdown menu, to the left of the right-side column, and above the footer. Right now there is some content is this main body area. What i am trying to achieve is that whenever any link is clicked on any of the other parts of the webpage, i want that content to be displayed in this main body. Right now i am copying this template to each and every page, but I want to keep this standard template as index.php and then replace main body content based on the link clicked. This is a php based website. Are there any examples where i can see how this can be achieved? or is there any standard procedure to do this. Please guide me, Thanks.
Here's a very simple way to do this:
index.php
<?php
function putPage($page) {
// put a list of allowed pages here
$allowed = array('page1', 'page2');
$page = trim($page);
$page = (in_array($page, $allowed)) ? $page : 'home';
echo #file_get_contents('.\html\\' . $page . '.html');
}
?>
<html>
<head>
<title>Title</title>
<!-- put stylesheets, js files, etc. here -->
</head>
<body>
<!-- you can have a nav bar or something here -->
<div class="navbar">
Page 1 Page 2
</div>
<?php putPage($_GET['page']); ?>
<!-- put a footer here -->
</body>
</html>
Then just put .html pages with the contents in an html subfolder.
The script will fetch them and insert them in the body.
There are a few ways you can achieve this. Off hand the two obvious ones I would say are:
Ajax to obtain content with event handlers attached to links/buttons/menus that produce maincontent specific to the request.
This requires server and client side scripting to achieve.
w3 ajax
Or alternatively use mod_rewrite with apache to determine what content to load in index.php page. For example with mod rewrite you may have a link http://www.site.com/subject/content/item# as a link structure. This could translate to www.site.com/index.php?subject=&content=&id= And these GET values would allow you to determine what to display in main content area.
This requires server side scripting and configuration of apache or (any web server with similar functionality to mod_rewrite).
mod_rewrite - apache
I use this:
<?php
$pag = array(1 => 'Home.php', 3 => '2.php');
echo require $pag[(int)#$_GET['p'] | 1];
?>
This is called either a Template View as far as you build your link specific HTML completely in PHP. You create a page layout template containing some wildcards. You load the template into a string and use string replacements or XML functions (more fancy but only suggestive if transformation is more complex).
Otherwise it is called Two Step View where you create the page layout template (as above) and a specific template for the links. Now first load the link specific template, put your dynamic content into (same techniques as above), load the page layout template and put the previous transformed specific template into.

Categories