I am new to Laravel and I am trying to load header, footer and the view file from controller in a common template and display the data from controller in the view file. But I get error
View ['admin.dashboard'] not found.
The dashboard file is present in the admin folder inside views.
Controller
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
class common extends Controller
{
public function login()
{
$data['title'] = 'Dashboard';
$data['template'] = 'admin/dashboard';
return view('common_template', compact('data'));
}
}
common_template.blade View
<?php echo View::make('includes/header'); ?>
<?php echo $template = "'".$data['template']."'";
echo View::make($template); ?>
<?php echo View::make('includes/footer'); ?>
When I add 'admin/dashboard' instead of $data['template'] directly in $template, it loads the dashboard file whereas it doesn’t load when i pass it as string from controller.
dashboard.blade view
<p><?php echo $data['title']; ?></p> // Printing the data from the controller
To include a Blade template into another template, use #include:
#include('admin.dashboard')
Or
#include($data['template']) // This should be the name of template, like 'admin.dashboard', but not path
Also, check if the view has the correct name and is in the right directory:
resources/views/admin/dashboard.blade.php
First of all, your code requires correction as per the Laravel Blade code standard. Try the below code:
common_template.blade View
#include('includes.header')
#yield('content')
#include('includes.footer')
dashboard.blade view
#extends('common_template')
#section('content')
{{$data['title']}}
#endsection
To include a Blade template into another template,
layouts/index.blade.php
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<!-- Site Title -->
<title>{{ $title }}</title> // Dynamic title
<link rel="stylesheet" href="{{ asset('website/css/main.css') }}">
#stack('css') // Internal CSS
</head>
<body>
#include('../website/layouts/header') // Include header
#yield('content') // Include content
#include('../website/layouts/footer') // Include footer
<!-- Start footer Area -->
<!-- End footer Area -->
<script src="{{asset('website/js/vendor/jquery-2.2.4.min.js ') }}"></script>
#stack('js') // Internal js
</body>
</html>
layouts/footer.blade.php
// Footer code
<h1>This area for footer code
layouts/header.blade.php
// Header code
<h1>This area for headercode
/home.blade.php
<?php $title = "dynamic title"; ?> // Title
#extends('layouts/index') // Include index page
#Push('css') // This is for internal js
*{
color: black;
}
#endpush
#section('content') // Section for content
This area for home page content
#stop // Content ended
#Push('js') // This is for internal js
<script>
$(document).ready(function() {
var loggedIn = {!! json_encode(Auth::check()) !!};
$('.send').click(function() {
if(!loggedIn) {
moda.style.display = "block";
return false;
}
});
});
#endpush
Related
I am trying to load a HTML template when a link is clicked. I have made a directive that contains templateUrl which loads a HTML file. I am calling a function when a link is clicked that appends a div with our custom directive "myCustomer" to a div already in index.html. whatever i have done so far is shown below, but it doesn't work.
index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example - example-example12-production</title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.1/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body ng-app="docsTemplateUrlDirective">
<div ng-controller="Controller">
show
<div id="d"></div>
</div>
</body>
</html>
script.js
(function(angular) {
'use strict';
angular.module('docsTemplateUrlDirective', [])
.controller('Controller', ['$scope', function($scope) {
$scope.showdiv = function(){
$("#d").append("<div my-Customer></div>");
};
}])
.directive('myCustomer', function() {
return {
templateUrl: 'my-customer.html'
};
});
})(window.angular);
my-customer.html
<p>DIV CONTENT</p>
Here is the link i was testing this code here
This is because the angular doesn't bind the directives if you append content like this,
you need to $compile service to do this and this will bind the directives against your $scope
so controller like,
.controller('Controller', ['$scope', '$compile', function($scope, $compile) {
$scope.showdiv = function(){
var compiledeHTML = $compile("<div my-Customer></div>")($scope);
$("#d").append(compiledeHTML);
};
}])
here is the DEMO
OR good to do like this,
use ng-if to create or removing element from html,
try this code
Controller,
....
$scope.anableCustomerDirective = false;
$scope.showdiv = function(){
$scope.anableCustomerDirective = true;
};
HTML
<body ng-app="docsTemplateUrlDirective">
<div ng-controller="Controller">
show
<div id="d">
<div my-Customer ng-if='anableCustomerDirective'></div>
</div>
</div>
</body>
Suggestion
if your main intention is to place a html content after the click, then you can use ng-include here and it will much cleaner and no need of a another directive.
<div id="d">
<div ng-include="templateURL"></div>
</div>
$scope.showdiv = function(){
$scope.templateURL = 'my-customer.html';
};
find the DEMO
Seems like directive is only meant to load template from it.I'd suggest you to use ng-include directive then
Markup
show
<div id="d"></div>
<div ng-include="showDiv ? 'my-customer.html': ''">
The most common way is to use $compile. More info: Dynamically add directive in AngularJS
Then your controller may look like this:
angular.module('docsTemplateUrlDirective', [])
.controller('Controller', ['$scope', '$compile', function($scope, $compile) {
$scope.showdiv = function(){
var el = $compile( "<div my-customer></div>" )( $scope );
$('#d').append( el );
};
}]);
Note that the directive invokation should look like this: <div my-customer>, not <div my-Customer></div> as you have in your code.
when you do it manually with append you actually do not run $apply or $digest so the directive is not run,
can you try to do it with ng-show or ng-if ... e.g
<body ng-app="docsTemplateUrlDirective">
<div ng-controller="Controller">
show
<div my-customer ng-if="showdiv"></div>
<div id="d"></div>
</div>
</body>
this way angular runs the $apply and the directive will be rendered.
I have divided my html-file into a header.php, content.php and footer.php
I would like to load the js files and the document.getready function either in the hader or in the footer file. But I got an error saying: Uncaught ReferenceError: $ is not defined.
In my header.php I load the following scripts in the head section:
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js" async></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.2.5/jquery.fancybox.js" async></script>`
And in my Footer after the closing </body>-Tag I call:
<script>
$(document).ready(function() {
if( !window.isCMS) {
// Group images by gallery using data-fancybox-group attributes
var galleryId = 1;
$('.editable-gallery').each( function() {
$(this).find('a').attr('data-fancybox', 'gallery-' + galleryId++);
});
$('.editable-gallery').each( function() {
$(this).find('img').attr('width', '200');
});
// Initialize Fancybox
$("[data-fancybox]").fancybox({
// Use the alt attribute for captions per http://fancyapps.com/fancybox/#useful
//beforeShow: function() {
// var alt = this.element.find('img').attr('alt');
//this.inner.find('img').attr('alt', alt);
//this.title = alt;
//}
});
}
});
</script>
In my content.php file I include my header.php and footer.php like this:
<?php include ("header.php"); ?>
<?php include ("footer.php"); ?>
How and where do I have to implement the script files and the document.getready function?
This is my Gallery Code in my content.php:
<div id="my-gallery" class="editable-gallery">
<img src="fotos/2018/rl/02022018/3.jpg" alt="">
<img src="fotos/2018/rl/02022018/1.jpg" alt="">
<img src="fotos/2018/rl/02022018/3.jpg" alt="">
</div>
I have to add the attr "data-fancybox" and "width" to work with fancybox.
1st:- The error comes from src="http://code.jquery.com/jquery-latest.min.js" it should be https instead of http >> src="https://code.jquery.com/jquery-latest.min.js"
2nd:- you can include js files or js code in <head> OR BEFORE </body>
3rd:- you can use <script></script> anywhere from <head> to </body> even before the line you including your jquery BUT use $(document).ready(function(){ //code here })
Note: if you have any plugins you must include the plugins after including jquery
your js code works fine
$(document).ready(function() {
//if( !window.isCMS) {
// Group images by gallery using data-fancybox-group attributes
var galleryId = 1;
$('.editable-gallery').each( function() {
$(this).find('a')
.attr('data-fancybox', 'gallery-' + galleryId++).find('img').attr('width' , '200');
});
// Initialize Fancybox
$("[data-fancybox]").fancybox({
// Use the alt attribute for captions per http://fancyapps.com/fancybox/#useful
//beforeShow: function() {
// var alt = this.element.find('img').attr('alt');
//this.inner.find('img').attr('alt', alt);
//this.title = alt;
//}
});
//}
});
<!-- 1. Add latest jQuery and fancyBox files -->
<script src="//code.jquery.com/jquery-3.3.1.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.2.5/jquery.fancybox.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.2.5/jquery.fancybox.min.js"></script>
<!-- 2. Create links -->
<div id="my-gallery" class="editable-gallery">
<img src="http://via.placeholder.com/350x150" alt="">
<img src="http://via.placeholder.com/350x150" alt="">
<img src="http://via.placeholder.com/350x150" alt="">
</div>
<!-- 3. Have fun! -->
My goal is to pass a jQuery script through a model with CodeIgneter.
This is the view where I linked the jquery.js file
<footer>
<p>© Company 2014</p>
</footer>
<script src="<?php echo base_url('assets/js/jquery.js');?>"> </script>
</div> <!-- /container -->
This is the model jquery
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Jquery extends CI_Model {
public function test(){
return
'<script>
$(document).ready(function() {
$("#submitForm").click(function(){
alert("test");
});
});
</script>';
}
}
In the controller I passed the script as following:
$this->load->model('jquery');
$data['testjs'] = $this->jquery->test();
$this->load->view('login/content',$data);
In the content view I echo the script:
...echo $testjs...
Unfortunately the script does not work as expected.
you need to include jquery library. Add this in your header view
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
and then this code in somewhere in view or header view
jQuery(document).ready(function() {
jQuery("#submitForm").click(function(){
alert("this is working file ");
});
});
you can use Dom crawler for that if you want to send html and jquery data pass through controller
https://github.com/dimabdc/PHP-Fast-Simple-HTML-DOM-Parser
or else you can set in header view file as above answer given
I have a div block that I only want to display on the first page. I mean, if the user is on
http://mywebsite.com/
it displays the div. But if he navigates to the second page of the posts
http://mywebsite.com/page/2
it hides that div. I am using Datalife Engine.
Div example:
<div class="example"> This is a test </div>
Can this be done?
follow this and all be worked fine.
<head>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="http://code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
if( $('#mainPage').length > 0 ) {
$("#hideMe").css({"display": "block"});
} else {
$("#hideMe").css({"display": "none"});
}
});//end doc ready function
</script>
</head>
<body>
<div id="mainPage"> </div>
<div id="hideMe">lorem ipsum</div>
</body>
hope it helps you
example http://jsfiddle.net/viktorino/56ea5/
For datalife engine, display just on the first page we use:
[page-count=1]Content goes here[/page-count]
Before I begin I have to say that I have recently started learning CodeIgniter, so I'm sorry if I repeat this subject once again.
In procedural php I would do something like this
// the header.php
<!DOCTYPE html>
<html>
<head>
<meta name="description" content="blah blah">
<title>My Site</title>
<link href="css/main.css" rel="stylesheet" media="screen">
<php? if($current_page == 'about.php'): ?>
<link href="css/secondary.css" rel="stylesheet" media="screen"> // or some embed styles (<stlye> ... </style>)
<?php endif; ?>
<script src="http://code.jquery.com/jquery.js"></script>
<script src="js/main_script.js"></script>
<php? if($current_page == 'contact.php'): ?>
<script src="js/validation.js"></script>
<?php endif; ?>
</head>
<body>
// end of header.php
include('template/header.php');
<h1>Heading1</h1>
<p>Lorem Ipsum...</p>
include('template/footer.php');
//footer.php
//maybe some js and here
</body>
</html>
So I would like to do something similar and in CI. All pages/views will have the same main styles or scripts, but in some cases, some specific pages (like contact.php) may include, and only in these pages, some specific styles or scripts (like the validation.js).
I have found this video that shows how to create a template/layout library using CI, but I'm not quite sure how I can apply this functionality to work properly.
Put the bottom class in libraries/Layout.php (your app not the sys). In the autoload add the library:
$autoload['libraries'] = array('layout');
In your controller just write $this->layout->render();
The class will render the layout views/layouts/default.php and the view views/$controller.views/$method.php
In the default layout just put
<?php $this->load->view($view,$data); ?>
and thats it.
The code is
<?php
if (!defined('BASEPATH')) exit('No direct script access allowed');
class Layout
{
public $data = array();
public $view = null;
public $viewFolder = null;
public $layoutsFodler = 'layouts';
public $layout = 'default';
var $obj;
function __construct()
{
$this->obj =& get_instance();
}
function setLayout($layout)
{
$this->layout = $layout;
}
function setLayoutFolder($layoutFolder)
{
$this->layoutsFodler = $layoutFolder;
}
function render()
{
$controller = $this->obj->router->fetch_class();
$method = $this->obj->router->fetch_method();
$viewFolder = !($this->viewFolder) ? $controller.'.views' : $this->viewFolder . '.views';
$view = !($this->view) ? $method : $this->view;
$loadedData = array();
$loadedData['view'] = $viewFolder.'/'.$view;
$loadedData['data'] = $this->data;
$layoutPath = '/'.$this->layoutsFodler.'/'.$this->layout;
$this->obj->load->view($layoutPath, $loadedData);
}
}
?>
I'm doing layout thing is like bellow.
I get content to data['content'] variable.
This is my controller.
class Article extends MY_Controller {
function __construct() {
parent::__construct();
$this->load->model('article_model');
}
public function index() {
$data['allArticles'] = $this->article_model->getAll();
$data['content'] = $this->load->view('article', $data, true);
$this->load->view('layout', $data);
}
This is my Layout.I'm using bootstrap layout.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<title>Starter Template for Bootstrap</title>
<base href="<?php echo base_url(); ?>" />
<!-- Bootstrap core CSS -->
<link href="assets/bootstrap3.0.1/css/bootstrap.min.css" rel="stylesheet">
<!-- Custom styles for this template -->
<!-- <link href="starter-template.css" rel="stylesheet">-->
<!-- Just for debugging purposes. Don't actually copy this line! -->
<!--[if lt IE 9]><script src="../../assets/js/ie8-responsive-file-warning.js"></script><![endif]-->
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#"> Article Management System</a>
</div>
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li class="active">Home</li>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#"> Admin <span class="caret"></span></a>
<ul class="dropdown-menu">
<li>Add Article</li>
<li>All Article</li>
</ul>
</li>
</ul>
</div><!--/.nav-collapse -->
</div>
</div>
<div class="container" style="margin-top: 80px;">
<?php echo $content; ?>
</div><!-- /.container -->
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
<script src="assets/bootstrap3.0.1/js/bootstrap.min.js"></script>
</body>
</html>
This is my content view
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="page-header">
<h4>All Articles </h4>
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>Title</th>
<th>Description</th>
<th></th>
</tr>
</thead>
<tbody>
<?php foreach ($allArticles as $row) { ?>
<tr>
<td><?php echo $row->title; ?></td>
<td><?php echo substr($row->description,0,100); ?> ....</td>
<td></td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
</div>
I have achieved the same thing with the following:
Put this code in your ./application/core/MY_Controller.php file:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class MY_Controller extends CI_Controller
{
protected $layout = 'layout/main';
public function __construct()
{
parent::__construct();
}
protected function render($file = NULL, &$viewData = array(), $layoutData = array())
{
if( !is_null($file) ) {
$data['content'] = $this->load->view($file, $viewData, TRUE);
$data['layout'] = $layoutData;
$this->load->view($this->layout, $data);
} else {
$this->load->view($this->layout, $viewData);
}
$viewData = array();
}
}
Create a layout folder inside ./application/views directory and then create your files with the entire html in it. Just put the <?php echo $content; ?> in that file where you want to put the dynamic content in it. Then in your controllers use $this->render(); and pass your file path and data. If you want to use a different layout for specific page just put the $this->layout = 'path_to_your_layout_file'; it will override the layout file to be used.
I have struggled with a similar problem not long ago. My solution to it was the following :
In your controller constructor create 2 arrays one of css files and one of js files and put in them the files common to all views.
And in each function in the controller add to them logic specific files.
For your example you'll have something like this :
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Home extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->page_data = array();
$this->page_data['css']=array('main.css','bootstrap.css');
$this->page_data['js']=array('main.js','bootstrap.js');
}
public function about()
{
array_push($this->page_data['css'],'secondary.css');
$this->load->view('main_layout',$this->page_data)
}
public function contact()
{}
}
And in your view file you'll just iterate over the $css and $js array and include them one by one.
You can extend that easily to include header and footer templates by pushing them into the page_data array.
I ended up switching to doing all the templating on the client-side with Backbone and using Code Igniter as a REST API only but this technique gave me relatively clean code for what I needed.
5 Simple Steps to create CodeIgniter Template:
Step #1
Template.php # libraries
Step #2
Write following code
/* Start of file Template.php */
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Template {
var $template_data = array();
function set($name, $value)
{
$this->template_data[$name] = $value;
}
function load($template = '', $view = '' , $view_data = array(), $return = FALSE)
{
$this->CI =& get_instance();
$this->set('contents', $this->CI->load->view($view, $view_data, TRUE));
return $this->CI->load->view($template, $this->template_data, $return);
}
}
/* End of file Template.php */
/* Location: ./system/application/libraries/Template.php */
Step #3
open config/autoload.php
at line 55 replace
$autoload['libraries'] = array('database', 'session','encrypt');
with this code
$autoload['libraries'] = array('database', 'session','encrypt', 'template');
Step #4
On my controller call template as
//start
$this->template->load(TEMPLATE_NAME, VIEW_NAME , $this->data);
//end
Step #5
On views
create a file as custom_template.php
And place there following code--
//start
<?php $this->load->view('elements/header'); ?>
<div><?php echo $contents;?></div>
<?php $this->load->view('elements/footer'); ?>
//end
N.B. In views in elements folder create two files as header.php And footer.php
I use this, in older version of CodeIgniter and it works for version 3 as well.
<?php
if (!defined('BASEPATH')) exit('No direct script access allowed');
class Layout
{
var $obj;
var $layout;
function Layout($layout = "layout_main")
{
$this->obj =& get_instance();
$this->layout = $layout;
}
function setLayout($layout)
{
$this->layout = $layout;
}
function view($view, $data=null, $return=false)
{
$loadedData = array();
$loadedData['content_for_layout'] = $this->obj->load->view($view,$data,true);
if($return)
{
$output = $this->obj->load->view($this->layout, $loadedData, true);
return $output;
}
else
{
$this->obj->load->view($this->layout, $loadedData, false);
}
}
}
?>
and to call this in the controller I use:
$this->layout->view('apps/apps', $data);