In my Layout, when I do this
<?php $js = APPLICATION_PATH."/../public/js"; ?>
<script src = <?php echo $js."/signup_layout_js.js"; ?> ></script>
I get a js error
http://proj_name/home/aman/Work/proj_name/public/js/signup_layout_js.js
My APPLICTION_PATH is getting appended to http://proj_name/, I dont want that.
But if I do this, it works fine on http://proj_name/ but breaks when i go to a controller/action like http://proj_name/Controller/Action
<script src ="./js/signup_layout_js.js"></script>
How can I correct this. Thanks.
Also in my index.php, APPLICATION_PATH is
// Define path to application directory
defined('APPLICATION_PATH')
|| define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
Thanks..
Link scripts like this:
<script src = "<?= $this->baseUrl() . '/js/signup_layout_js.js' ?>" ></script>
Or use headScript helper:
//put this in header
<?= $this->headScript(); ?>
//put this before closing body tag
<?= $this->inlineScript() ?>
//and this anywhere in you code ($this is view object)
$this->headScript()
->prependFile($this->baseUrl() . '/js/jquery-1.7.2.min.js')
->appendFile($this->baseUrl() . '/js/flying-header.js')
->appendScript('
var google_conversion_id = 9999999;
var google_custom_params = window.google_tag_params;
var google_remarketing_only = true;');
Your entire path is part of the src for your scripts because you are prepending it. Try echoing the value of your APPLICATION_PATH constant. This is not the correct behaviour for referencing static files in web applications.
In your case, you should look into using Zend Framework's built-in headScript and inlineScript view helpers for this. You shouldn't need to write the script DOM tags yourself.
Related
I am trying toinclude css file in the following code.
Config :
$config['base_url'] = 'http://localhost/ASOFT/Projects/CI_search';
$config['site_url'] = 'http://localhost/ASOFT/Projects/CI_search/index.php';
$config['js'] = 'assets/js';
View:
<link rel="stylesheet" href="<?php echo $base?>/<?php echo $css?>/style.css">
<link rel="stylesheet" href="<?php echo $base?>/<?php echo $css?>/bootstrap.min.css">
<script src="<?php echo $base?>/<?php echo $js?>/jquery.min.js"></script>
<script src="<?php echo $base?>/<?php echo $js?>/jquery.js"></script>
<script src="<?php echo $base?>/<?php echo $js?>/bootstrap.min.js"></script>
I put the css file in CI_search/css and js file in CI_search/assets/js
I got the error undefined variable css and undefined variable js.Please provide solution for this problem.
UPDATE
Controller:
public function index() {
$this->data = array(
'site' => $this->config->item('site_url'),
'base' => $this->config->item('base_url'),
'css' => $this->config->item('css'),
'js' => $this->config->item('js'),
'image'=>$this->config->item('image')
);
$data = $this->data;
$data['error'] = '';
$this->load->view('index',$data);
}
As far as i can see, you din't declared $config['css'] in your config file, so it's normal to get undefined variable error for css. But you shouldn't have problem with js.
When declaring your base_url use trailing slash at the end (eg. "http://localhost/fancysite/")
Also you can use CI's url helper to use functions like base_url() or site_url() and many more. (as #Likee suggested).
config.php
// this should be the first variable in CI's config.php
$config['base_url'] = "http://localhost/ASOFT/Projects/CI_search/";
// many more lines with other configuration variables
// ..................................................
// ..................................................
// ..................................................
// your own configuration variables at the end of file
$config['css'] = 'css/';
$config['js'] = 'assets/css/';
$config['image'] = 'images/';
controller
public function index() {
// loading url helper to use base_url() function in the view,
// if you load this helper in autoload.php you don't need to load it here again
$this->load->helper('url');
// if you didn't declare data as class property
// you can simply use
// $data = array(
// 'css' => $this->config->item('css'),
// 'js' => $this->config->item('js'),
// 'image'=>$this->config->item('image')
// );
$this->data = array(
'css' => $this->config->item('css'),
'js' => $this->config->item('js'),
'image'=>$this->config->item('image')
);
// you really don't need the line below
// $data = $this->data;
$this->data['error'] = '';
$this->load->view('index',$this->data);
}
view
<link rel="stylesheet" href="<?php echo base_url($css . 'style.css'); ?>">
<link rel="stylesheet" href="<?php echo base_url($css . 'bootstrap.min.css'); ?>">
<script src="<?php echo base_url($js . 'jquery.min.js'); ?>"></script>
<!-- do you really need to include jquery.js while you included jquery.min.js above? but here we go :) -->
<script src="<?php echo base_url($js . 'jquery.js'); ?>"></script>
<script src="<?php echo base_url($js . 'bootstrap.min.js'); ?>"></script>
Probably you will need to use url helper a lot. So you can autoload it in autoload.php file in config folder. it must be somewhere around line 90
$autoload['helper'] = array('url');
There are many ways to include css and js file in codeigniter.
This how I do it.
FIRST: Create a folder outside the application folder and named it any named you liked but I prefer to named it as resources. Create a sub folders like js, css, images and others. Place all your files in here for future references.
SECOND: Open the the contants.php saved in application/config and paste this code.
define('CSS', 'http://localhost/yourfolder/resources/css');
define('JS', 'http://localhost/yourfolder/resources/js');
define('IMAGES', 'http://localhost/yourfolder/resources/images');
NOTE: Update this code depends on your needs.
THIRD: On your view file, you can access this files by,
<link rel="stylesheet" href="<?php echo(CSS.'bootstrap.min.css'); ?>">
<script type="text/javascript" src='<?php echo(CSS.'bootstrap.min.css'); ?>'></script>
Refer to this link. How can I include the CSS file in CodeIgniter?
I hope this helped.
Bind your variables to view like this:
$this->load->view('viewName', $config);
And array $config should be available in your controller method.
Instead setting $config['base_url'] you can use function base_url().
well if at all possible determine what your path structure will be and then just use it in the view with base_url() .
<link href="<?php echo base_url();?>assets/css/bootstrap.min.css" rel="stylesheet">
<script src="<?php echo base_url();?>assets/js/blahblah.js"></script>
you can even have a few simple templates, and then call the appropriate template.
if that is impossible - then push this logic and output to a model or similar so that it can be called by different controllers. otherwise you are going to have to update folder names and file paths in your controllers.
I have a directory structure like this:
www/
index.php
my-library/
my-library.php
assets/
my-library.css
images/
loading.gif
I need my-library.php to inject stylesheets into index.php. To do so, I need to get the relative path from index.php to my-library/ -- which in this particular case, would simply be "my-library".
From within my-library.php, is it possible for me to acquire this relative path?
Or must index.php supply it, with something like the following?
<?php
require "my-library/my-library.php";
$mlib->linkroot='my-library';
?>
To clarify, below I have included a more detailed representation of what I'm trying to do:
index.php:
<?php require "my-library/my-library.php"; ?>
<!doctype html>
<head>
<title>Testing My Library</title>
<?php $mlib->injectAssets(); ?>
</head>
<body>..</body>
my-library.php:
<?php
class MyLibrary(){
public $rootpath;
public $linkroot;
function __construct(){
$this->rootpath= __DIR__; // absolute path to my library's root directory (for serverside use)
$this->linkroot = "???"; // relative path to my library's root from index.php (for clientside use, like linking in stylesheets)
}
function injectAssets(){
$csslink = $this->linkroot.'/assets/my-library.css';
echo '<link href="'.$csslink.'" rel="stylesheet" />';
}
}
$mlib = new MyLibrary();
?>
The line I'm interested in figuring out, would be $this->linkroot = "???";.
I'm practically trying to acquire the string that was used to include/require the current script.
I got it! I only had to build a Rube Goldberg Machine to do it!
Thanks PHP.
$linkroot = ascertainLinkroot();
function ascertainLinkroot(){
return makeRelativePath(
getTopScriptPath(),
__DIR__
);
}
function getTopScriptPath(){
$backtrace = debug_backtrace(
defined( "DEBUG_BACKTRACE_IGNORE_ARGS")
?DEBUG_BACKTRACE_IGNORE_ARGS
:FALSE );
$top_frame = array_pop($backtrace);
$top_script_path = $top_frame['file'];
return $top_script_path;
}
function makeRelativePath($from,$to){
// Compatibility
$from = is_dir($from) ?rtrim($from,'\/').'/' :$from;
$to = is_dir($to) ?rtrim($to,'\/').'/' :$to;
$from = str_replace('\\','/',$from);
$to = str_replace('\\','/',$to);
//----------------------------
$from = explode('/',$from);
$to = explode('/',$to);
$path = $to;
foreach($from as $depth => $dir) {
if ($dir === $to[$depth]) { // find first non-matching dir
array_shift($path); // ignore it
} else {
$remaining = count($from)-$depth; // get number of remaining dirs to $from
if ($remaining>1){
// add traversals up to first matching dir
$padLength = -(count($path)+$remaining-1);
$path = array_pad($path, $padLength, '..');
break;
} else {
$path[0] = './'.$path[0];
}
}
}
return rtrim(implode('/', $path),'\/');
}
So, basically, I use the makeRelativePath function to calculate a relative path from the top script's absolute path to the current script's absolute directory path (__DIR__).
I realized that I'm actually looking for the relative path to the library from the top script, not just the parent script -- because the top script is the one where clientside assets will need to be referenced in relation to.
Naturally, PHP doesn't just give you the top script's absolute path. On some environments, the top script's path can be available as a $_SERVER variable, however environment independence is important for me, so I had to find a way.
getTopScriptPath was my solution, as it uses debug_backtrace to find it (creepy, I know), but it is the only environment-independent way to fetch it (to my knowledge).
Still hoping for a more elegant solution, but am satisfied that this one works.
I believe this is what you're looking for:
$this->linkroot = basename(pathinfo($_SERVER['REQUEST_URI'], PATHINFO_DIRNAME));
You can remove basename() to get the full path. Basically, you can run the following code:
echo '<pre>';
var_dump($_SERVER);
echo '</pre>';
If the path you're looking for isn't there in some shape or form, then it simply isn't available and you will have no other choice but to hard code it, or at least hard code part of it.
Have you tried doing a relative link from the root? If not, you might try something like this, if I understand your folder structure.
<link href="/my-library/assets/my-library.css" rel="stylesheet" type="text/css" />
Links like this in any page within your site will pull the same stylesheet, up or down the site structure.
Is it possible to have multiple
<?php echo $this->headScript(); ?>
in one view?
Like
<?php $this->headScript()->appendFile('foo.js'); ?>
<?php echo $this->headScript(); ?>
some other html here
<?php $this->headScript()->appendFile('bar.js'); ?>
<?php echo $this->headScript(); ?>
Currently it duplicates foo.js, so is there a way to clean the headScript container?
UPD:
The exact problem is that I'm not satisfied with how <?php $this->headScript()->captureStart(); ?> works. Because I cannot specify <script type="..."> there thus my IDE doesn't treat the code between captureStart and captureEnd as a javascript.
So I want to split output into 2 parts, with <script type="text/javascript"> between them
PS: I know that it is better to move js to a separate file, but in this particular place I need it to be specified inline
May be I'm missing smth, why you can't use setFile instead appendFile ?
The issue is separation of multiple .js sections. This is totally doable as the viewhelpers for headlink, headscript, etc. implement the ArrayAccess interface.
This is how I do it - using the ZF2 Bootstrap (from Skeleton to be consistent):
<!-- allows for comments as well, within diff. .js script tag outputs -->
<?php
$this->headScript()
->prependFile($this->basePath() . '/js/bootstrap.min.js')
->prependFile($this->basePath() . '/js/jquery.min.js')
->prependFile($this->basePath() . '/js/respond.min.js', 'text/javascript', array('conditional' => 'lt IE 9',))
->prependFile($this->basePath() . '/js/html5shiv.js', 'text/javascript', array('conditional' => 'lt IE 9',));
// Notice! below we'll echo out what we have in the headScript placeholder object
echo $this->headScript();
// Now, since it implements ArrayAccess interface, we can use exchangeArray() method
// to clear out (if you will) the stored array of .js files we've previously assigned
$this->headScript()->exchangeArray(array());
?>
<!-- Some other js file(s) I have to include -->
<?php
$this->headScript()
->appendFile($this->basePath() . '/js/scripts.js', 'text/javascript');
// same as above for consistency
echo $this->headScript();
$this->headScript()->exchangeArray(array());
?>
This should help tremendously.
The way this usually works is <?php echo $this->headScript(); ?> is in your layout. It will echo out all the scripts you assign it by calling headScript() once. I usually have a few scripts in my Boostrap, like jquery or modernizer.
//BootStrap.php
protected function _initView() {
//Initialize view
$view = new Zend_View();
$view->doctype(Zend_Registry::get('config')->resources->view->doctype);
$view->headMeta()->appendHttpEquiv('Content-Type', Zend_Registry::get(
'config')->resources->view->contentType);
$view->headLink()->setStylesheet('/css/normalize.css');
$view->headLink()->appendStylesheet('/css/blueprint/src/liquid.css');
$view->headLink()->appendStylesheet('/css/blueprint/src/typography.css');
$view->headLink()->appendStylesheet(
'/javascript/mediaelement/build/mediaelementplayer.css');
$view->headLink()->appendStylesheet('/css/main.css');
$view->headLink()->appendStylesheet('/css/nav.css');
$view->headLink()->appendStylesheet('/css/table.css');
//add javascript files
$view->headScript()->setFile('/javascript/mediaelement/build/jquery.js');
$view->headScript()->appendFile('/javascript/modernizr.js');
//add it to the view renderer
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper(
'ViewRenderer');
$viewRenderer->setView($view);
//Return it, so that it can be stored by the bootstrap
return $view;
}
If I need to add scripts later it's just a matter of passing them in the controller usually in preDispatch() :
public function preDispatch() {
if ($this->getRequest()->getActionName() == 'play') {
$this->_helper->layout->setLayout('play');
$this->view->headScript()->appendFile(
'http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js'
);
$this->view->headScript()->appendFile(
'/javascript/mediaplayer/jwplayer.js'
);
}
}
One call to <?php echo $this->headScript(); ?> will echo out all 4 of these script files.
The same kind of thing can be done with inline scripts using the inlineScript() helper. The inlineScript() helper is the one you use if you need javascript somewhere other then the head of you file.
I need a method of inserting javascript which is controller/action specific into a layout. That javascript needs to go inside the <head> of the document, far from where normal content is placed. I already have an infrastructure in place which allows use of multiple views per page, and the Zend_Layout I already have takes full advantage of this:
<?php
$script = $this->layout()->script;
if (!is_null($script)) : ?>
<script type="text/javascript"> // <![CDATA[
<?php echo $script; ?>
// ]]>
</script>
<?php endif; ?>
However, I'd like the script output to be automatically selected, just like the normal view is automatically placed into $this->layout()->content of the layout by default. I understand this facility is provided by the ViewRenderer class. Basically, what I'd like to do is check for an instance of /VIEWPATH/scripts/CONTROLLER/ACTION.js.php, and render it as the script named output segment if it exists.
I could relatively simply create a Zend_Controller_Plugin which would automatically do that in post dispatch, but then controllers would have no way of setting values on the script's view. I also would need some way of replicating how the ViewRenderer controller plugin is inflecting the controller and action names.
Ideally I'd just somehow tack this on to the ViewRenderer helper, but it doesn't seem to support that kind of thing.
Am I going about this entirely wrong? Is there some mechanism for embedding page specific Javascript built into the framework? (I can't be the only person with this problem....)
Billy3
Extending my comment
Here is the doc for what are you looking for:
http://framework.zend.com/manual/1.12/en/zend.view.helpers.html#zend.view.helpers.initial.headscript
You can use captureStart() and create your scripts dynamically inside each related view.
With this approach you don't need to create *.js.php files.
I think there is no build in mechanism. Iam using an small controller plugin like this:
class My_Controller_Plugin_JavaScript extends Zend_Controller_Plugin_Abstract
{
/**
* preDispatch
* Check controller name, and include javaScript library
*
* #param Zend_Controller_Request_Abstract $request
* #return void
*/
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
$layout = Zend_Layout::getMvcInstance();
$view = $layout->getView();
$controller = $request->getControllerName();
$jsFile = $controller . '-lib.js';
$jsPath = $view->baseUrl() .
'/js/' . $controller .
'/';
$sPath = PUBLIC_PATH . DIRECTORY_SEPARATOR . 'js' . DIRECTORY_SEPARATOR;
$sPath .= $controller . DIRECTORY_SEPARATOR . $jsFile;
if (file_exists($sPath)) { // load as last js (offset 100)
$view->headScript()->offsetSetFile(
100,
$jsPath . $jsFile
);
}
}
}
It adds an js file by controller name. Layout iam echoing it
<?= $this->headScript(); ?>
You could extend it to use action to. Iam sure there are better ways, but it works!
Zend Framework had view helpers to add javascript file(first snippet) + text javascript(second snippet)
you could add javascript files
<?php
$this->headScript()->appendFile($this->baseUrl("js/jquery-1.4.2.min"))
->appendFile($this->baseUrl("js/jquery-ui-1.8.2.custom.min"));
$this->headScript()->appendScript("js/dummy.js");
echo $this->headScript();
?>
then in some where else , you could add
<?php $this->headScript()->captureStart() ?>
// start jquery functions
var action = '<?php echo $this->baseUrl ?>';
$('foo_form').action = action;
// end jquery functions
<?php $this->headScript()->captureEnd() ?>
The following assumptions are made:
The script will be appended to the
stack. If you wish for it to replace
the stack or be added to the top, you
will need to pass 'SET' or 'PREPEND',
respectively, as the first argument to
captureStart(). The script MIME type
is assumed to be 'text/javascript'; if
you wish to specify a different type,
you will need to pass it as the second
argument to captureStart(). If you
wish to specify any additional
attributes for the tag, pass
them in an array as the third argument
to captureStart().to captureStart().
source : http://framework.zend.com/manual/en/zend.view.helpers.html
After reading this thread: How to force browser to reload cached CSS/JS files?
I would like to know if there is any built-in function or easy way in Symfony that automatically forces a reload by appending a random querystring or timestamp to the link when it has discovered that javascript / css file has been modified. (Normally, people use the use_javascript function to generate the <script> tag)
There is no built-in mechanism, but a little creativity means you can do this just about anywhere in your code, from view.yml to layout.php to each individual action.
The view.yml method is easy enough:
apps/frontend/config/view.yml:
stylesheets: [main?v=<?php echo time() ?>, reset?v=<?php echo time() ?>, layout?v=<?php echo time() ?>]
Although I think this is a little too active, and I tend to use either the SVN revision or a overall project version number:
stylesheets: [main?v=<?php echo sfConfig('app_project_version') ?>, reset?v=<?php echo sfConfig('app_project_version') ?>, layout?v=<?php echo sfConfig('app_project_version') ?>]
where app_project_version is set in apps/frontend/config/app.yml. Methods for layout.php and actionSuccess.php should be easy enough from here:
<?php use_stylesheet('blah?v='.sfConfig::get('app_project_version')); ?>
instead of setting a version for each stylesheet you include, it is better to have it done automatically for all included stylesheets, no matter if you use view.yml or use_stylesheet() method. You need to implement this helper method and
include the helper in your applications settings.yml, so that it becomes available to alle your actions.
`
function include_versioned_stylesheets()
{
$response = sfContext::getInstance()->getResponse();
sfConfig::set('symfony.asset.stylesheets_included', true);
$html = '';
foreach ($response->getStylesheets() as $file => $options) {
$filepath = sfConfig::get('sf_web_dir') . '/' . stylesheet_path($file);
if(file_exists($filepath)) {
$file .= '?v=' . filectime($filepath);
}
$html .= stylesheet_tag($file, $options);
}
echo $html;
}
`
in your layout.php call this inside your header area. make sure there is no further call to include_stylesheets(), as this is an extended version to it.
same can be done with include_javascripts.