I'm working on a Django app and using angular as frontend. I want to create a s.p.a. using routes. But I'm unable to access the templates, because they are in templates folder. My directory structure is like :
root
|-- templates
| |-- index.html
| |-- view1.html
| |-- view2.html
|-- static
|-- app.js
|-- angular.js
|-- angular-route.js
I'm a newbie in angularjs, so pls be descriptive in your answer's.
I can't change the directory structure,
Or if I'm working with render to string then how can I load the view with a api call which return me the html on page load?
Django templates != Angular templates. Don't mix them. Angular templates are static files from Django's point of view; keep them in the static folder.
I would suggest separating your Angular application from your Django application if you can.
First, if you haven't done so, learn about REST API endpoints and use Django REST framework or a similar library to surface your application's data via REST API endpoints. This allows you to get your data by visiting URL's on your Django development server without it having to be served in through the Django templating engine, which is what I'm assuming you're doing at the moment. Something like:
http://localhost:8000/api/users/
Will return a list of users that looks something like:
[{
username: 'Bob'
email: 'bob#gmail.com'
}, {
username: 'George',
email: 'george#gmail.com'
}]
Then you can serve up your angular application as a static file through another development server using something like http-server through node.
Now your angular application can be served up through http://localhost:8080/ and your django application can be served up through http://localhost:8000/. Your data for your angular application is now accessed strictly through HTTP calls, which decouples the previously intertwined and mangled frameworks.
This allows you to use angular's templating engine instead of trying to keep track of where your template files are being served through your Django server. So your folder structure for angular can look something like:
app
|-- index.html (includes your main angular application)
|-- templates/ (templates here)
|-- app/ (app files here)
This is just an example though, a good source on how to write and organize your application, which I find useful, can be found at https://github.com/johnpapa/angular-styleguide.
Let me know if you have anymore questions!
Related
I have a react application build with create-react-app. Its using octoberCMS as the backend fetching data using Axios calls from the frontend. Till now I was developing keeping the build content of react inside a directory named 'react' in the root directory of octoberCMS installation. Hence the URL I was hitting was http://example.com/react/.
The problem is now I am done with the development phase and look forward to deployment. But I want my front-end to be served at http://example.com and backend to be served at http://example.com/backend (backend served as I want). How can I achieve this? I am fairly new to both frameworks.
I have tried keeping the build content along with the rest of the octoberCMS
First build your react app that will give you vendor.js[third party scripts] and your app.js[your actual app]
put them in to theme directory assets something
Then In Ocotber CMS make page with URL /:url? and paste your index.html content there.
it will be your root div and including js html, change path for js which points to the build js which you put in theme directory.
now what happens when anybody come to site
- we are serving same content as we do in dev build
- index.html with root tag and needed js
Now if use hit any other url like https://www.example.com/test/etc it also will be catch by /:url? (and all other requests) and home page served and our react app will work as we needed.
if any questions please comment.
I have developed a REST application using Spring in NetBeans IDE.
Here is the relevant dir structure:
I want to integrate Angular functionality into it, but will prefer to keep it as a single app, rather than separate Angular and Spring apps.
The main index.html file should show the template home.html on the front page.
The Problem:
Adding HTML files to the templates folder doesn't seem to work in the Angular application. If I try to access the index.html and home.html files through Angular, I get a 404 error, but I can open them directly.
Here's the controller in my Spring application for these two files:
#RequestMapping("/")
public String index() {
return "index";
}
#RequestMapping("/home")
public String home() {
return "home";
}
I have written AngularJS code before by itself, and I didn't have any problems.
Am I mixing some things that I shouldn't?
Do I create all my AngularJS code in a separate folder, away from src/main/resources?
Spring maps your files placed in src/main/resources/static to the root directory of your application. This means a CSS file in your src/main/resources/static/css/ folder can be accessed by simply using the /css relative path.
Static resources such as CSS, Javascript, templates or images should therefore be placed in the static folder, where Angular will be able to access it.
This restriction does not extend to your main index.html file, and you can place it in the main project directory or under templates.
Answer taken from JBNizet in comments.
We are in process of structuring our code folder project, which will contain multiple independent angular apps ( they may share common services, which can be injected into the apps )
We should be able to build and deploy each app separately ( have a independent gulpfile for each app)
I am not really sure how to share common services, i guess we would need a top level app which will contain one of the app when deployed.
How and where can i configure which app to be built or served when top level app is accessed.
I have looked at manually bootstrapping the angular app, but not sure where that code would go ?
Should each app have its own bower_components folder, or can they share from the top level app itself.
Any direction, links to blog will help.
Here is what i have come up so far:
apps/
common/
appOne/
components/
services/
appOne.js
index.html
appTwo/
...
...
bower_components/
index.html
package.json
Problem
I have a static SPA site built with Angular and hosted on Amazon S3. I'm trying to make my pre-rendered pages accessible by crawlers, but I can't redirect the crawlers requests since Amazon S3 does not offer a URL Rewrite option and the Redirect rules are limited.
What I have
I've added the following meta-tag to the <head> of my index.html page:
<meta name="fragment" content="!">
Also, my SPA is using pretty URLs (without the hash # sign) with HTML5 push state.
With this setup, when a crawler finds my http://mywebsite.com/about link, it will make a GET request to http://mywebsite.com/about?_escaped_fragment_=. This is a pattern defined by Google and followed by others crawlers.
What I need is to answer this request with a pre-rendered version of the about.html file. I've already done this pre-rendering with Phantom.js, but I can't serve the correct file to crawlers because Amazon S3 do not have a rewrite rule.
In a nginx server, the solution would be to add a rewrite rule like:
location / {
if ($args ~ "_escaped_fragment_=") {
rewrite ^/(.*)$ /snapshots/$1.html break;
}
}
But in Amazon S3, I'm limited by their redirect rules based on KeyPrefixes and HttpErrorCodes. The ?_escaped_fragment_= is not a KeyPrefix, since it appears at the end of the URL, and it gives no HTTP error since Angular will ignore it.
What I've tried
I've started trying using dynamic templates with ngRoute, but later I've realized that I can't solve this with any Angular solution since I'm targeting crawlers that can't execute JavaScript.
With Amazon S3, I have to stick with their redirect rules.
I've managed to get it working with an ugly workaround. If I create a new rule for each page, I'm done:
<RoutingRules>
<!-- each page needs it own rule -->
<RoutingRule>
<Condition>
<KeyPrefixEquals>about?_escaped_fragment_=</KeyPrefixEquals>
</Condition>
<Redirect>
<HostName>mywebsite.com</HostName>
<ReplaceKeyPrefixWith>snapshots/about.html</ReplaceKeyPrefixWith>
</Redirect>
</RoutingRule>
</RoutingRules>
As you can see in this solution, each page will need its own rule. Since Amazon limits to only 50 redirect rules, this is not a viable solution.
Another solution would be to forget about pretty URLs and use hashbangs. With this, my link would be http://mywebsite.com/#!about and crawlers would request this with http://mywebsite.com/?_escaped_fragment_=about. Since the URL will start with ?_escaped_fragment_=, it can be captured with the KeyPrefix and just one redirect rule would be enough. However, I don't want to use ugly URLs.
So, how can I have a static SPA in Amazon S3 and be SEO-friendly?
Short Answer
Amazon S3 (and Amazon CloudFront) does not offer rewrite rules and have only limited redirect options. However, you don't need to redirect or rewrite your URL requests. Just pre-render all HTML files and upload them following your website paths.
Since a user browsing the webpage has JavaScript enabled, Angular will be triggered and will take control over the page which results into a re-rendering of the template. With this, all Angular functionalities will be available for this user.
Regarding the crawler, the pre-rendered page will be enough.
Example
If you have a website named www.myblog.com and a link to another page with the URL www.myblog.com/posts/my-first-post. Probably, your Angular app has the following structure: an index.html file that is in your root directory and is responsible for everything. The page my-first-post is a partial HTML file located in /partials/my-first-post.html.
The solution in this case is to use a pre-rendering tool at deploy time. You can use PhantomJS for this, but you can't use a middleware tool like Prerender because you have a static site hosted in Amazon S3.
You need to use this pre-render tool to create two files: index.html and my-first-post. Note that my-first-post will be an HTML file without the .html extension, but you will need to set its Content-Type to text/html when you upload to Amazon S3.
You will place the index.html file in your root directory and my-first-post inside a folder named posts to match your URL path /posts/my-first-post.
With this approach, the crawler will be able to retrieve your HTML file and the user will be happy to use all Angular functionalities.
Note: this solution requires that all files be referenced using the root path. Relative paths will not work if you visit the link www.myblog.com/posts/my-first-post.
By root path, I mean:
<script src="/js/myfile.js"></script>
The wrong way, using relative paths, would be:
<script src="js/myfile.js"></script>
EDIT:
Below follows a small JavaScript code that I've used to prerender pages using PhantomJS. After installing PhantomJS and testing the script with a single page, add to your build process a script to prerender all pages before deploying your site.
var fs = require('fs');
var webPage = require('webpage');
var page = webPage.create();
// since this tool will run before your production deploy,
// your target URL will be your dev/staging environment (localhost, in this example)
var path = 'pages/my-page';
var url = 'http://localhost/' + path;
page.open(url, function (status) {
if (status != 'success')
throw 'Error trying to prerender ' + url;
var content = page.content;
fs.write(path, content, 'w');
console.log("The file was saved.");
phantom.exit();
});
Note: it looks like Node.js, but it isn't. It must be executed with Phantom executable and not Node.
Is there a way for you to use Laravel trans() or Lang::get() method using (lang folder) in AngularJS app?
Laravel view that displays an angular view with multiple controllers.
<div ng-view></div>
I have in public_html folder all my templates for my app.
With the default structure of a Laravel app you can't access the app/lang directory. However, you could write a grunt task or a Laravel command, that process all you language files and copy the results in your public directory to make it publicly available for your Angular app.