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.
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.
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.
I'm developing a Wordpress video plugin. I want the video to start loading AFTER the rest of the page has loaded. I have:
Created videosplash.php which contains code to create a div #video-splash.
Created videosplash-video.php which contains code for loading the video itself. This code works perfectly when it is included directly within the above DIV.
Attempted to use jquery bind the second PHP file to div #video-splash with directions for this to happen AFTER the rest of the page has loaded.
Both PHP files are within the same plugin directory.
I've tried the following ways of doing this with no luck; and I can't find any clarification of the matter by searching online.
Attempted Method 1
As a JS script normally calls things from whatever directory it is running from, I would have thought this should work - but it doesn't:
<script type="text/javascript">
$(window).bind("load", function() {
$('#video-splash').load('videosplash-video.php');
});
</script>
Attempted Method 2
I've also tried this way to load the file dynamically, but I don't think the plugins_url is a valid means of calling the file in javascript:
<script type="text/javascript">
$(window).bind("load", function() {
$('#video-splash').load( plugins_url('/assets/php/videosplash-video.php',__FILE__ ) );
});
</script>
and
<script type="text/javascript">
$(window).bind("load", function() {
$('#video-splash').load( plugins_url('/videosplash-video.php',__FILE__ ) );
});
</script>
What am I missing folks? And thank you in advance
You cannot include wordpress plugins url via javascript,
one thing you can do, first hide the video div by giving the style="display:none", then on load you can make it display:block using javascript
for example consider this following is your video div,
<div id="video-splash" style="display:none;">
some video content inside
</div>
then use javascript to enable it after page load like this,
$(document).on("load", function() {
$('#video-splash').show();
});
In angularJS you generally have an index page that includes the header and footer directly, and a div such as <div ng-view></div> or <section ui-view></section> where partial html pages are injected based on a routing file in app.js. For example:
.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: "/home",
templateUrl: "home/index.html"
})
.state('about', {
url: "/about",
templateUrl: "about/index.html"
})
.state('contact', {
url: "/contact",
templateUrl: "contact/index.html"
})
$urlRouterProvider.otherwise('/home');
})
Then whenever someone clicks a hyperlink to a different part of the site, the router decides which partial gets injected into the index page. The problem with this is that the urls include hashtags (example.com/#/home) and you can only get rid of this by configuring the website's server to run html5mode, which I can't do for this particular site.
So I'm wondering what is the PHP equivalent to achieve this type of routing functionality. I figured you can use include() for the header and footer, but am lost on how to handle the actual html partials using php.
Assuming you're using Apache, you could use:
$_SERVER['REQUEST_URI']
This PHP variable holds the URI given to access the current page (i.e., URL minus "http://domain.com"). If you had a large number of possible URIs that needed to be handled by a single PHP script, you could use a switch statement:
switch ($_SERVER['REQUEST_URI']) {
case "/page1.php": // what to do if $_SERVER['REQUEST_URI'] contains "/page1.php"
include 'page1.php';
break; // end of this case
case "/page2.php":
include 'page2.php';
break;
...
default: // what to do if no match is found
include '404.php';
}
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" />