The CodeIgniter application was developed much earlier without plans to integrate ReactJS at that time. A later requirement was added to integrate another ReactJS project with this backend and replace the current frontend (views).
The CodeIgniter application is not done as a RESTful API. The .php view files could not be replaced with .js files of the reactjs app as the server is Apache.
Running a nodejs server would not render the CodeIgniter views.
Bootstrap, jquery, and simple javascript can be included within the view of the CodeIgniter application. But is it possible to replace the PHP view files in CodeIgniter with javascript files?
The PHP view files do not need to be replaced with js files. JavaScript can easily be added to PHP files using <script> tags. Below is the Add React in One Minute demo in a CodeIgniter app.
To integrate the React demo into CodeIgniter start with a simple controller - React.php
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class React extends CI_Controller
{
public function index()
{
$this->load->view('react_view');
}
}
The "view" file is straight from the React demo but it's put in a .php file instead of .html.
The only change made to the demo code is in the script tag at the bottom of the page. My assets folder is on the same level as CodeIgniter's /application folder. There are subfolders in assets for css, js, and images.
/public_html
/application
/system
/assets
/js
/css
/img
So I've changed the src for the tag that loads like_button.js to work with my file layout.
The "view" file react_view.php
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Add React in One Minute</title>
</head>
<body>
<h2>Add React in One Minute</h2>
<p>This page demonstrates using React with no build tooling.</p>
<p>React is loaded as a script tag.</p>
<p>
This is the first comment.
<!-- We will put our React component inside this div. -->
<div class="like_button_container" data-commentid="1"></div>
</p>
<p>
This is the second comment.
<!-- We will put our React component inside this div. -->
<div class="like_button_container" data-commentid="2"></div>
</p>
<p>
This is the third comment.
<!-- We will put our React component inside this div. -->
<div class="like_button_container" data-commentid="3"></div>
</p>
<!-- Load React. -->
<!-- Note: when deploying, replace "development.js" with "production.min.js". -->
<script src="https://unpkg.com/react#16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom#16/umd/react-dom.development.js" crossorigin></script>
<!-- Load our React component. -->
<script src="assets/js/like_button.js"></script>
</body>
</html>
/assets/js/like_button.js
'use strict';
const e = React.createElement;
class LikeButton extends React.Component {
constructor(props) {
super(props);
this.state = { liked: false };
}
render() {
if (this.state.liked) {
return 'You liked comment number ' + this.props.commentID;
}
return e(
'button',
{ onClick: () => this.setState({ liked: true }) },
'Like'
);
}
}
// Find all DOM containers, and render Like buttons into them.
document.querySelectorAll('.like_button_container')
.forEach(domContainer => {
// Read the comment ID from a data-* attribute.
const commentID = parseInt(domContainer.dataset.commentid, 10);
ReactDOM.render(
e(LikeButton, { commentID: commentID }),
domContainer
);
});
Here's a boilerplate that you can use.
https://github.com/cyruzin/codeigniter-react-boilerplate
React is used for single page applications. Codeigniter is a PHP framework. Nobody forbids you to include react apps inside codeigniter. The react app polls data from API provided by codeigniter. You can use multiple codeigniter controllers or views to define different react states, or you can just use one controller, one view and multiple models and define states with react alone.
React is not in opposition to codeigniter. Codeigniter doesn't care if you use jquery, angular or react. From the view on it's not a codeigniter's business.
Related
I want to mix basic HTML generated by Php and VueJS components without having to use VueJS all the way down to the lowest dom leaf.
The parent layout has the Vue app applied all the headers navs assides etc are Vue components and the main content on most pages are still plain HTML generated by PHP.
I want to upgrade small parts of the main content with Vue components but I cant use them once HTML has been used:
Php script generates the entire dom
<div id="app"> VueJS instance mounts here.
<Cats>This component works perfectly here.
<div id="main Content">More HTML content generated by PHP.
<Cats> Cats does nothing here.
<Cats> works perfectly fine in the upper DOM but after rendering some basic HTML the app will no longer populate components further down.
Php can render JS in a script tag but it's unable to use any imports.
Is there any way to get the Vue instance to treat all <Cats> tags as the Cats component regardless of where it is written on the page?
So far I have tried:
async components.
portals using mounting portals.
creating another Vue instance and mounting it to another ID.
Any ideas?
EDIT: The things I tried previously may be been blocked by the mishmash of multiple UI modernization attempts in this monolith I have inherited.
So I would not rule those out for others facing this situation.
If you are dynamically passing the template which is coming from an API or from any other source into your Vue instance. There is a way to access that via v-html attribute but before using that please have a look at note below.
Note that the contents are inserted as plain HTML - they will not be compiled as Vue templates.
Hence, As you are trying to bind/render the Component itself and it's not a plain HTML. So it will not processed by Vue's template compiler.
Possible solution is that you can get a component name and props from your PHP API instead of whole HTML template.
You can also achieve the same by using Vue compile option. Here is the demo :
Vue.component('Cats', {
props: ['msg'],
template: '<h3>{{ msg }}</h3>'
});
// Template coming from PHP
const template = `<div id="main Content"><Cats msg="Meow... Meow..."></div>`
var app = new Vue({
el: '#app',
data: {
compiled: null
},
mounted() {
setTimeout(() => {
this.compiled = Vue.compile(template);
})
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<Cats msg="Meow...">
</Cats>
<component :is="compiled"></component>
</div>
In the end, I had to manually add a JS file to the build configs containing a global window.ExtraVue with a setup function like so:
import Cats from 'files/Cats.vue';
window.ExtraVue = {
setup: function(data) {
new Vue({
el: '#extra-vue',
data: data,
components: {
Cats
},
template: '<Cats/>'
})
}
};
The setup function is then called at the very end of the PHP script.
<script>window.ExtraVue.setup(<?=json_encode($array)?>)</script>
The setup function can now create a new Vue instance for each component that needs to be out on its own.
Ideally, it would be great if VueJS could just replace matching tags with components.
I have php framework based on Zend library and I'd like to use angularjs script in phtml file but I have problem how to include template edytuj_row.phtml located in:
ProjectName->SourceFiles->application->admin->views->settings->edytuj.phtml
<div row-settings></div>
<script type="text/javascript">
var app = angular.module('mainApp', []);
app.directive('rowSettings', function(){
return {
templateUrl: 'edytuj_row.phtml'
};
});
</script>
Both files edytuj_row.phtml and edytuj.phtml are localizated in the same directory but edytuj_row.phtml is not seen. What is right path in templateUrl ? In this situation in place of <div row-settings></div> is loaded recurently main web page instead of template.
Angular has no access to Zend files (templates). You need to set valid URL to templateUrl (eg. /admin/users/edytuj-row)
You probably have edytujAction and edytujRowAction. Check what URL path directs to edytujRowAction (probably in Bootstrap.php) and set it in templateUrl.
Before I started with Joomla I developed a html page that uses jqplot, and that pages worked/works fine.
Now I want to include jqplot in a custom joomla (3.3) component that I'm developing, but when calling the component (by means of main menu item) no chart is shown.
UPDATE DEFAULT.PHP (JOOMLA) CODE FURTHER TO COMMENT:
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
$document = JFactory::getDocument();
//add jqplot libraries
JHtml::_('jquery.framework');
$document->addScript(JPATH_ROOT.'/media/system/js/jquery.jqplot.min.js');
$document->addStyleSheet(JPATH_ROOT.'/media/system/js/jquery.jqplot.min.css');
$document->addScript(JPATH_ROOT.'/media/system/js/jqplot.barRenderer.min.js');
$document->addScript(JPATH_ROOT.'/media/system/js/jqplot.categoryAxisRenderer.min.js');
$document->addScript(JPATH_ROOT.'/media/system/js/jqplot.pointLabels.min.js');
$document->addScript(JPATH_ROOT.'/media/system/js/jqplot.enhancedLegendRenderer.js');
$document->addScript(JPATH_ROOT.'/media/system/js/weqlib.js');
?>
<head>
<script type="text/javascript">
jQuery(document).ready(function(){
var plot1 = jQuery.jqplot ('chart1', [[3,7,9,1,4,6,8,2,5]]); //copied from example at http://www.jqplot.com/tests/line-charts.php
}); //$(document).ready
</script>
</head>
<!--<h1><?php echo $this->msg; ?></h1>-->
<h1>Prosumer Dashboard </h1>
<div id="chart1" style="width:600px; height:250px;"> </div>
I think the way I call the libabries is wrong (I know for sure the jqplot function call is ok, as I also copied this from my old html file).
Any idea what I'm doing wrong and how to fix this?
You should add javascript to the head of the page in the following way...
<?php
$document = JFactory::getDocument();
$document->addScript('/media/system/js/sample.js');
?>
Your script currently will be attempting to load the javascript in relation to the page's URL, not in relation to your component's URL, so it will not be finding them.
Also, Joomla 3 comes with JQuery - load it like this (possibly in your template rather than your component)...
JHtml::_('jquery.framework');
Note that this runs in no conflict mode, so you have to replace any '$' in your jquery scripts with the 'jQuery'. You can also make it run in conflict mode...
JHtml::_('jquery.framework', false);
However, this may cause problems if your site has any other libraries running.
I am maintaining Zend application with ExtJS 3 based views. Recently, I am working on migrating to ExtJS 4 MVC based application.
Background
With ExtJS 3 I used to combine ExtJS library + all my JS files and include that in Zend layout (let's call that combine.js).
<script type="text/javascript" src="combine.js"></script>
All I needed to do was to met dependencies in combined file.
Now, trying to accomplish ExtJS 4 MVC approach with Zend generating my views, I am running into multiple problems with the new Ext.Loader. My Zend layout consists of
<script type="text/javascript">
Ext.application({
name: 'demo',
appFolder: 'app',
controllers: [
// controllers list here
],
launch: function()
{
// viewport + page items
}
});
</script>
Moreover, in HEAD section I still maintain the same approach to include one combined file (ExtJS 4 library + all my js files). In theory, I have all js dependencies met since I include the whole library before my code.
Problem
I am running into multiple problems with new class loading mechanism.
Let's assume I have only one controller with one view and one store on ExtJS side:
Ext.define('demo.myModule.controller.MyGrid', function() {
extend: 'Ext.app.Controller',
stores: [ 'demo.myModule.store.MyStore' ],
views: [ 'demo.myModule.view.MyStore' ]
...
});
Rendering such page ends up with Ext.Loader trying to fetch not existing resource :
GET http://myPage/demo/myModule/store/MyStore.js?_dc=1390226857962 404 (Not Found)
Disabling Ext.Loader ends up with :
Uncaught Error: Ext.Loader is not enabled, so dependencies cannot be resolved dynamically. Missing required class: demo.myModule.controller.MyGrid
Since ExtJS 4 is a really popular library, someone must have hit the same stumbling block before. What is the proper way to tackle such problem ?
BTW. I am asking that question having already spent couple of days on ExtJS documentation + official tutorials, tried Sencha CMD but I fail to get what the exact problem is.
EDIT:
I have added a sample project showing the problem: https://github.com/mirfilip/extjs-zend. You can see app.js containing simple class demo.myModule.view.Panel. In application/layouts/scripts/layout.phtml you can see that the whole library + app.js is loaded (in order). When you try to render the project it will show the blank page. However, if you go to layout and uncomment lines 23-33 (and comment out appending of app.js in line 11) and render, it works well. The only difference is where my class is defined in. There should be no possible time race between classes as Ext.application creation is wrapped it Ext.onReady. Any ideas ?
I don't use Zend Studio, so I cannot give a specific answer. I will just show you my code, how I integrate ExtJs into my own homebrewed framework.
This is the html code on my development site, which will use Ext.Loader to load the classes dynamically.
<!-- <x-compile> -->
<!-- <x-bootstrap> -->
<link rel="stylesheet" href="bootstrap.css">
<script src="ext/ext-dev.js"></script>
<script src="bootstrap.js"></script>
<!-- </x-bootstrap> -->
<script src="ext/locale/ext-lang-fr.js"></script>
<script src="app.js"></script>
<!-- </x-compile> -->
This will then compile to :
<link rel="stylesheet" href="resources/Mb-all.css"/>
<script type="text/javascript" src="app.js"></script>
This snipped is found in the build/production/MyApp/index.php folder. I have then a build script that takes this file and copies it where it should be for the php framework to work.
I hope this will give you an idea to solve your specific problem.
Important: app.js is a autogenerated file by sencha cmd. It is not the same thing in the development environment and in the test environment.
In the development it just contains this text:
/*
This file is generated and updated by Sencha Cmd. You can edit this file as
needed for your application, but these edits will have to be merged by
Sencha Cmd when upgrading.
*/
Ext.application({
name: 'Mb',
extend: 'Mb.Application',
autoCreateViewport: true
});
In the production envrionment it contains the full, minified javascript source of the app.
Probably you have to indicate paths to Ext classes before your combined app js file. I'm using paths relative to domain root ('/app' not 'app').
<script>
Ext.Loader.setConfig({
paths : {
'demo' : '/app'
},
enabled: true
});
</script>
<script src="combine.js" />
Has anyone managed to integrate HTML5 Boilerplate in the YII PHP Framework (specifically the folder structure and build process)?
Boilerplate recommends using the #import when adding styles to the head.
<style>#import(/example.css);</style>
Yii uses the ClientScript model to add
<link type="text/css" src="/example.css" />
Use the Yii::app()->clientScript Model to register the file. Yii allows you to register script files as needed, per controller or per view. Therefor your http requests can be minimal. I would suggest registering the required scripts/css in the main layout and add other scripts as they are needed with the
Yii::app()->clientScript->registerScriptFile();
Yii is based on the MVC model. The V is for view. The view foldes contain the html elements your model and controller will adjust based on data types. Inside the view folder Yii uses the layout folder to define layouts.
$this->layout = 'main';
That line will look for:
Protected -> views -> layout -> main.php
The layout folder should contain main, _htmlHead, _header and _footer. The renderPartial will be used for render the different layout parts. It's like a php include for HTML. The second param of $this->render or $this->renderPartial is used to pass data to the view. For example nav data:
$this->renderPartial('_footer', array('nav'=>array('/link/'=>'Link Name')));
In the _htmlHead register the needed elements using the Yii::app()->clientScript. If you want to use a different version of jQuery then use the ScriptMap model, don't register jQuery twice. Yii's coreScript, validation and paging are based on jQuery.
$cs = Yii::app()->clientScript;
$cs->registerCssFile('/css/base.css');
$cs->registerScriptFile('/js/base.js', CClientScript::POS_END);
/* Load Script at END of DOM tree: CClientScript::POS_END */
http://www.yiiframework.com/doc/api/1.1/CClientScript
In the past I've used the config.php file in Yii to set an assetsLocaion parameter. If I move my assets it won't break the site.
Yii::app()->clientScript->registerScriptFile(Yii::app()->param->assetsLocation.'/js/example.js');
The basic layout of the boilerplate will be defined in the layout/main.php. Check out the theme documentation: http://www.yiiframework.com/doc/guide/1.1/en/topics.theming
Layout File Might look like this:
<!doctype html>
<?php $this->renderPartial('//layouts/_Htmlhead); ?>
<body>
<div id="container">
<?php $this->renderPartial('//layouts/_header); ?>
<div id="main" role="main">
<?php echo $content; ?>
</div>
<?php $this->renderPartial('//layouts/_footer); ?>
</div>
<?php $this->renderPartial('//layouts/_footerScripts); ?>
</body>
</html>
Check my Yii BoilerPlate and Bootstrap Integration
https://github.com/drumaddict/YiiApp
A simple Yii HTML5 Boilerplate theme is available at https://github.com/neam/yii-html5-boilerplate
There is a very detailed Wiki article by Antonio Ramirez titled:
YiiBoilerplate - Setup a professional project structure in seconds
http://www.yiiframework.com/wiki/374/yiiboilerplate-setup-a-professional-project-structure-in-seconds/
Sources for this setup:
https://github.com/clevertech/YiiBoilerplate
What about
https://github.com/clevertech/YiiBoilerplate
I think they Uses HTML5Bilerplate