Codeigniter - Load a specific JS library on a specific view - php

I'm trying to load the google maps API ie:
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true">
in my head template. But because I've only got one page with a google map on it (I'd rather not have the API load for all files), how would I send the message from the controller through to the view that I wish to load this particular JS file?
Thanks for your help.

CodeIgniter has a segments class. You would be able to run some code like:
<?php if($this->uri->segment(1) == 'map') { ?>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true">
<?php } ?>
When on page http://yoursite.com/map/ it will load the script.

One solution is to either use a template library that has javascript/css "injection" - see:
http://williamsconcepts.com/ci/codeigniter/libraries/template/reference.html#utilities
$this->template->add_js('js/jquery.js');
$this->template->add_js('alert("Hello!");', 'embed');
for more information.
If you don't want to use a template library, do something like this:
*assuming on the "Map" controller, and that you need the JS file on the default page.
class Map extends CI_Controller {
function __construct()
{
parent::__construct();
}
function index()
{
$scripts = array(
'<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true">' . "\n",
'<script>something</script>');
/* this method lets you add multiple...*/
$data['scripts'] = $scripts;
$this->load->view('my_map/index', $data);
}
}
in your view:
if(isset($scripts))
{
foreach($scripts as $script)
{
echo $script;
}
}
essentially you build an array of script files/css files (whatever), then check for its prescence and dump it in the head section of your view.
I'd personally go for the template option.
Also note CI2.0 has a new javascript driver might be worth a read

<?php
/**
* Head files loader
* #author azhar
**/
function headscripts($path)
{
if(is_string($path))
{
echo "<script type='text/javascript' src='". base_url($path) ."'></script>\n";
}elseif(is_array ($path)){
foreach ($path as $p) {
echo "<script type='text/javascript' src='". base_url($p) ."'></script>\n";
}
}
}
function headlinks($path)
{
if(is_string($path))
{
echo "<link rel='stylesheet' href='". base_url($path) ."'/>\n";
}elseif(is_array ($path)){
foreach ($path as $p) {
echo "<link rel='stylesheet' href='". base_url($p) ."'/>\n";
}
}
}
?>
Add this file in your helper_directory under the name head_helper. In your controller inside an action use this code
$data['headscripts'] = array('js/main.js');
And in your view file use this function
headscripts($headscripts);
For stylesheet use this
headlinks($headlinks);
And yes do not forget to load the helper using autoload.php file in config folder like this
$autoload['helper'] = array('url', 'file','head');

Thanks for your answers guys, I ended up doing a mixture of Ross and leaf dev's suggestions before I found your answers here, so I guess I was on the right track.
My controller has:
$data['head'] = array('specificjs');
$this->load->view('view',$data);`
and my view has:
if(isset($head)){
foreach($head as $item){
$this->load->view('js/'.$item);
}
}
and my 'specificjs' view has what's required.
This way I can load as many custom scripts as I want and have the code in a view not a controller.
Thanks again, but keep any further suggestions coming!

write a helper for this. Pass the scripts names in an array and inside the helper function iterate over them and print the scripts

Related

Subpanel Edit View

I have custom code on my Contacts Edit View via the file custom/modules/Contacts/views/view.edit.php. I want the same code to work for the Contact subpanel in other modules. How should I do this?
Below is the code I used:
In custom/modules/Contacts/view/view.customedit.php
require_once 'include/MVC/View/views/view.edit.php';
class ContactsViewEnjayedit extends ViewEdit
{
public function __construct()
{
parent::ViewEdit();
$this->useForSubpanel = true;
$this->useModuleQuickCreateTemplate = true;
}
protected function _displayJavascript()
{
echo '<script type="text/javascript" src="custom/modules/Contacts/js/jquery-1.11.0.min.js"></script>';
echo '<script type="text/javascript" src="custom/modules/Contacts/js/NjContact.js"></script>';
parent::_displayJavascript();
}
}
This took me way too long to figure out as well and I am happy to share the quite easy answer with you!
In your custom view.edit.php file add the following line inside the __construct() method:
$this->useForSubpanel = true;
That should do the trick!

how to include public resources to typo3 extbase extension

I'm building an extension that creates a backend module that enables be_users to resize images.
I'm trying to add / include css and javascript files by using the pageRenderer but the files are never included I can only apply css if add it directly in the fluid Template using a style tag and include the javascript file with a script tag.
I tried something like this in the controller
protected $pageRenderer;
....
$this->pageRenderer = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Page\\PageRenderer');
$this->pageRenderer->addCssFile('/typo3conf/ext/extKey/Resources/Public/css/styles.css');
$this->pageRenderer->loadJquery();
also tried with a viewHelper
namespace Vendor\ExtKey\ViewHelpers;
class AddJsFileViewHelper extends \TYPO3\CMS\Fluid\ViewHelpers\Be\AbstractBackendViewHelper {
public function render() {
$doc = $this->getDocInstance();
$pageRenderer = $doc->getPageRenderer();
$pageRenderer->loadJquery();
}
}
and in my tempate
{namespace pager=Vendor\ExtKey\ViewHelpers}
<f:layout name="Default" />
<f:section name="main">
<pager:addJsFile />
...
still nothing
I'm not sure how you define the template for your backend, but it seems this usually happens using the backend container view helper which already has functions for that:
<f:be.container
addCssFile="{f:uri.resource(path:'css/style.css')}"
addJsFile="{f:uri.resource(path:'js/scripts.js')}">
[your templates content]
</f:be.container>
In TYPO3 7.6.X, It has to be like following
<f:be.container
includeCssFiles="{style:'{f:uri.resource(path:\'css/style.css\')}'}"
includeJsFiles="{script:'{f:uri.resource(path:\'js/script.js\')}'}"
>
<!-- Template Code -->
</f:be.container>
As includeCssFiles and includeJsFiles requires array to be passed, we
can include any number of js and css.
i think the problem was my ViewHelper need to renderChilden and start/end page
current implementation is like this
the ViewHelper
namespace Vendor\ExtKey\ViewHelpers;
class AddPublicResourcesViewHelper extends \TYPO3\CMS\Fluid\ViewHelpers\Be\AbstractBackendViewHelper {
public function render() {
$doc = $this->getDocInstance();
$pageRenderer = $doc->getPageRenderer();
$extRelPath = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath("ext_key");
$pageRenderer->addCssFile($extRelPath . "Resources/Public/css/styles.css");
$pageRenderer->loadJquery();
$pageRenderer->addJsFile($extRelPath . "Resources/Public/js/app.js");
$output = $this->renderChildren();
$output = $doc->startPage("title") . $output;
$output .= $doc->endPage();
return $output;
}
}
the template
{namespace pager=Vendor\ExtKey\ViewHelpers}
<f:layout name="Default" />
<f:section name="main">
<pager:addPublicResources />
Pagerender::loadJjquery is working and accessible like this
TYPO3.jQuery(function($) {
});

Autoload a view on every page with codeigniter

So I have my views split up basically between three (3) files:
-- Header file
$this->load->view('templates/header', $data);
-- Main Body file
$this->load->view('login_view', $data);
-- Footer file
$this->load->view('templates/footer', $data);
Now I just recently started building, but I've noticed it's really annoying to retype the header and footer on every controller to tell it to load. Is there a way to automatically load the header and footer view on every request?
I found an article long time ago, but i can't seem to find it now, basically the author, (which i forgot) override the showing of output. this method of output will access your views regarding the given controller/method and will try to search in your views directory automatically.
Use at your own risk
Application/core/MY_COntroller.php
----------------------------------------------------------------------------
class MY_Controller Extends CI_Controller
{
protected $layout_view = 'layouts/application'; // default
protected $content_view =''; //data
protected $view_data = array(); //data to be passed
public function __construct()
{
parent::__construct();
}
public function _output($output)
{
if($this->content_view !== FALSE && empty($this->content_view)) $this->content_view = $this->router->class . '/' . $this->router->method;
$yield = file_exists(APPPATH . 'views/' . $this->content_view . EXT) ? $this->load->view($this->content_view, $this->view_data, TRUE) : FALSE ;
if($this->layout_view)
{
$html = $this->load->view($this->layout_view, array('yield' => $yield), TRUE);
echo $html;
}
}
}
Application/views/layouts/layout.php
----------------------------------------------------------------------------
<html>
<head>
<title>master layout</title>
</head>
<body>
<!-- this variable yeild is important-->
<div><?=$yield;?></div>
</body>
</html>
This is what i use to create my template. Basically you need a directory structure as follows.
+Views
|+layouts
||-layout.php
the layout.php will serve as your master template
How to use?
extend the controller
class User Extends MY_Controller
{
public function create_user()
{
//code here
}
public function delete_user()
{
//use a different master template
$this->layout_view = 'second_master_layout';
}
public function show_user()
{
//pass the data to the view page
$this->view_data['users'] = $users_from_db;
}
}
Just create directory in your views and name it with the controller name i.e user then inside it add a file you named your method i.e create_user
So now your Directory structure would be
+Views
| +layouts
| |-layout.php
| |-second_master_layout.php
| +user
| |-create_user.php
Just Edit the code to give you a dynamic header or footer
Here is the simple example which i always do with my CI project.
Pass the body part as a $main variable on controller's function
function test(){
$data['main']='pages/about_us'; // this is the view file which you want to load
$data['something']='some data';// your other data which you may need on view
$this->load->view('index',$data);
}
now on the view load the $main variable
<html lang="en">
<head>
</head>
<body>
<div id="container">
<?php $this->load->view('includes/header');?>
<div id="body">
<?$this->load->view($main);?>
</div>
<?php $this->load->view('includes/footer');?>
</div>
</body>
</html>
In this way you can always use index.php for your all the functions just value of $main will be different.
Happy codeing
Using MY_Controller:
class MY_Controller extends CI_Controller {
public $template_dir;
public $header;
public $footer;
public function __construct() {
parent::__construct();
$template_dir = 'templates'; // your template directory
$header = 'header';
$footer = 'footer';
$this->template_dir = $template_dir;
$this->header = $header;
$this->footer = $footer;
}
function load_views ($main, $data = [], $include_temps = true) {
if ($include_temps = true) {
$this->load->view('$this->template_dir.'/'.$this->header);
$this->load->view($main);
$this->load->view('$this->template_dir.'/'.$this->footer);
} else {
$this->load->view($main);
}
}
}
Then load it like: $this->load_views('login_view', $data);
You can do with library.
Create a new library file called template.php and write a function called load_template. In that function, use above code.
public function load_template($view_file_name,$data_array=array()) {
$ci = &get_instatnce();
$ci->load->view("header");
$ci->load->view($view_file_name,$data_array);
$ci->> load->view("footer");
}
You have to load this library in autoload file in config folder. so you don't want to load in all controller.
You can call
$this->template->load_template("index",$data_array);
If you want to pass date to view file, then you can send via $data_array
There is an article on this topic on ellislab forums. Please take a look. It may help you.
http://ellislab.com/forums/viewthread/86991/
Alternative way: Load your header and footer views inside the concern body view file. This way you can have batter control over files you want to include in case you have multiple headers and footer files for different purposes. Sample code shown below.
<html lang="en">
<head>
</head>
<body>
<div id="container">
<?php $this->load->view('header');?>
<div id="body">
body
</div>
<?php $this->load->view('footer');?>
</div>
</body>
</html>

Multiple headScript() outputs

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.

Zend_Framework -- How do I put Javascript in the layout?

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

Categories