How to create css folder working both locally and thru GAE? - google-app-engine

I have the following folders structure:
project-folder
- templates
- css
vk.css
index.html
app.yaml
script.py
I would like to be able:
run index.html without GAE
run index.html thru GAE (referenced at script.py as templates/index.html)
In both cases vk.css should be used. How should I define that at app.yaml and at index.html? Url is http://localhost:8080/something/.
I've made it working with GAE, index.html:
<link type="text/css" href="/css/vk.css" rel="stylesheet" />
app.yaml:
- url: /css/
static_dir: templates/css
But it doesn't work locally.

If you want your browser to be able to render the template directly off the filesystem, you can't use site-relative URLs (eg, ones that begin with a /) - when reading off your filesystem, site relative URLs are relative to your filesystem root. Instead, use relative urls (eg, ../css/vk.css), and make sure that the filesystem structure matches your URL structure.

Related

In React, why would one be using %PUBLIC_URL% instead of relative urls?

I'm tinkering with React.
In the index.html template generated by create-react-app, the favicon.ico is referenced through the use of %PUBLIC_URL%.
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
This comment is right after, explaining that %PUBLIC_URL% is better than relative url.
<!--Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.-->
I am not sure I understand what a non-root public URL is. I reckon is deploying your app on something like www.mydomain.com/subfolder instead of directlyon www.mydomain.com.
I'm not sure either why this tag should be concerned with client-side routing.
I thought that PUBLIC_URL was there to allow developers to not worry about the link tag href value that could be different between development environment and production environment.
Since the content of the public folder is copied in the build folder, I think this issue could be juste as much solved by using a relative url. In both configuration (www.mydomain.com/subfolder/index.html www.mydomain.com/index.html) the favicon would be found right next to the index.html file.
What am I missing?

How to deploy React on IIS?

When working on localhost, the app is assumed to be on root of the local dev server
localhost:50001/index.html
But when deploying to a remote IIS server, there are other web apps running there, and each individual app must be created as an "Application" (IIS terminology)
So for example, the 'Default Web Site' is on port 80; other apps (also on port 80) have their own AppName.
MYSERVERNAME/App1/
MYSERVERNAME/App2/
MYSERVERNAME/MyReactApp/
So now to get to my React App i have an additional path
http://MYSERVERNAME/MyReactApp/index.html
The index.html produced by 'npm run build' contains absolute paths;
To make my deployment work, I manually edited the index.html to contain relative paths
So for example, instead of:
<script type="text/javascript" src="/static/js/main.d17bed58.js"></script>
I added a .(dot) in front of all paths to get:
<script type="text/javascript" src="./static/js/main.d17bed58.js"></script>
This works mostly, and all scripts load initially. BUT I am not happy with the result, because any links and client-side routes (i.e from react-router) that I click within the app, will revert to assume the app is hosted on the root of the webserver. i.e.
http://MYSERVERNAME/
http://MYSERVERNAME/Home
http://MYSERVERNAME/MyWorkOrder/
http://MYSERVERNAME/MyWorkOrder/123456
Furthermore, if I type any of the links directly on the browser (or refresh the page), it will fail obviously.
To recap. the question is I need to maintain the "true" path http://MYSERVERNAME/myReactApp at all times, when deploying to IIS. How to do that?
From the docs:
Building for Relative Paths
By default, Create React App produces a build assuming your app is hosted at the server root.
To override this, specify the homepage in your package.json, for example:
"homepage": "http://mywebsite.com/relativepath",
This will let Create React App correctly infer the root path to use in the generated HTML file.
For example:
<script type="text/javascript" src="/static/js/main.xyz.js"></script>
will become:
<script type="text/javascript" src="/relativepath/static/js/main.xyz.js"></script>
If you are using react-router#^4, you can root <Link>s using the basename prop on any <Router>.
More information here.
For example:
<BrowserRouter basename="/calendar"/>
<Link to="/today"/> // renders <a href="/calendar/today">
What i ended up doing
1) After npm run build, change absolute paths to relative paths within index.html (example href="./etc..." and src="./etc...")
2) use basename in <BrowserRouter basename="/MyReactApp"/> (as per the answer by #mehamasum)
3) And finally, when doing page refresh on a non-existent SERVER route, you need to redirect what would otherwise be a 404, to the index.html, and let the client-side react-router library do its job. How? In IIS Manager, go to the IIS section\Error Pages\double-click\Edit 404 Status code, and in the 'Edit Custom Error Page' dialog, choose 'Execute a URL on this site', and enter the absolute path /MyReactApp/index.html

SailsJs - Serving Angular App from Assets

Within a new SailsJs application I'm trying to serve an angular app from the assets folder. Considering assets/admin/index.html I can access localhost:1337/admin, however, none of the additional js files or sub-directories can be accessed. I've even checked the .tmp/public folder and everything is copying over correctly but when I try to refer to any file within the admin folder other than index.html it can not be found.
Referring to angular module in index.html
<!--Sailes IO Library-->
<script src="/js/dependencies/sails.io.js"></script>
<!--Vendor Scripts-->
<script src="/js/angular-animate.js"></script>
<script src="/js/angular-aria.js"></script>
<script src="/js/angular-material.js"></script>
<script src="/js/angular-messages.js"></script>
<script src="/js/angular.js"></script>
<script src="/js/release/angular-ui-router.js"></script>
<!--Admin Application Definition-->
<script src="/admin/app.js"></script>
<script src="/admin/config/router.js"></script>
However, app.js is not being served!
Can I not do it this way? How can I access my angular application files from the admin folder?
To load an angular application in sails.js you need to serve the index.html file from the views folder.
so in you config/routes.js
'/': {
view: 'homepage'
}
this means when you hit the root of you application then homepage.ejs from the views folder is served
copy the contents of assest/admin/index.html file in homepage.ejs and if necessary check that all the link and script tags have the file path relative to assets folder.
once the homepage is served you can use angular ui router for routing purpose
Note--
change your
localhost:1337/admin to
localhost:1337
After reading the documentation a little more in-depth, sails will also serve index.html files found in the assets folder. So I created a new folder, inside that folder I created a new index.html and app.js file, and then lifted. My index.html file was then available at a url that matched my folder name. My folder was called "admin" so navigating to localhost:1337/admin loaded my index.html page.
As far as serving the other dependencies, I used grunt-bower and a new grunt task to start serving my bower_components over to my assets/vendor folder.

Integrate Ext JS 4.1 MVC application in a rewriten URL (mod_rewrite) in development and production

Creating a new Ext JS 4.1.1 app based on the file structure section in Sencha's MVC Application Architecture guide I end up with this structure:
/wwwroot
/myapplication
/app
/controller
/view
app.js
/extjs-4.1.1
The app.js file contains:
Ext.Loader.setConfig({
enabled: true
});
Ext.application({
appFolder: '/myapplication/app',
autoCreateViewport: true,
name: 'MyApplication',
controllers: [
...
]
});
All fine. I then include the app.js to be outputted in my server-side MVC application (not to be confused with the client-side Ext JS MVC structure). The language used and structure of the server-side application is of no importance to this question, but the result of the output is. In development, the URL of the application is:
http://servername/someidentifier1/someidentifier2
As in many applications, mod_rewrite is used to give meaning to the identifiers and map the URL to server-side code. These identifiers do not map to "physical" directories. The output of this URL is:
<!DOCTYPE html>
<html>
<head>
<title>MyApplication</title>
<link href="/extjs-4.1.1/resources/css/ext-all-debug.css" media="screen" rel="stylesheet" type="text/css" >
<script type="text/javascript" src="/extjs-4.1.1/ext-debug.js"></script>
<script type="text/javascript" src="/myapplication/app.js"></script>
</head>
<body>
</body>
</html>
Ext JS is not at the default recommended location, being /wwwroot/myapplication/extjs-4.1.1, but instead one level up since it is shared between multiple applications. If you look back at the app.js above, you also notice the appFolder setting which needs to be set in order for this to work with the "non existing" URL.
This all works fine in development, but the next step is to generate a "build" of the code with the Sencha SDK Tools (question is based on version 2.0.0 Beta 3 for Windows).
This is where it goes wrong. I take these steps:
Command line I go into the /wwwroot/myapplication directory.
I execute sencha create jsb -a http://servername/someidentifier1/someidentifier2 -p myapplication.jsb3 to generate a jsb3 file.
I execute sencha build -p myapplication.jsb3 -d .
The build fails. In this case because it tries to find the custom code for e.g. controllers in the path c:\...\myapplication\myapplication\app\controller: the current path + the appFolder setting. You would assume running it one level higher would be better, but then it cannot find the (shared) extjs-4.1.1 directory.
I would guess time will make the Ext JS MVC structure and SDK Tools more flexible and deviating slightly from the default structure is not recommended. All acceptable, but on the other hand: integrating Ext JS 4.x (Ext JS in an MVC way) with URL rewriting (mod_rewrite) must be a very common practice too?
Any suggested working set up/structure would be highly appreciated.
Goals should be:
No manual editing of the jsb3 file.
Keeping the extjs-4.1.1 directory at the top level to be shared among applications.
Having no app.html file since it is never used in server-side MVC applications and would otherwise require manual updates.
A nice extra would be to have the content of app.js inside the server-side generated HTML since it would then be able to receive dynamically generated parameters.
Couple things.
First - you don't need to specify absolute path for ExtJs library and for your app in the loader.
...
appFolder: 'app' // should be enough
...
Second - as for differences between build and production - I ended up having two .html files - index.html and index-dev.html. These files don't get changed (once you set them up) so it's not a problem to keep them in sync.
You use index-dev.html for your development needs, debug and also for build process. Basically this file is configured for your local development environment.
index.html just uses combined and minified version of your app.js and configured for production deployment.
Using mod rewrite you can use a slightly modified .htaccess file from Symfony
<IfModule mod_rewrite.c>
RewriteEngine On
#<IfModule mod_vhost_alias.c>
# RewriteBase /
#</IfModule>
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ app.php [QSA,L]
</IfModule>
This file let you
get resource from server if they are real files (css, js, images, etc.)
convert url parts to query parameters if there aren't matches on server filesystem.
This should work on your setup, just change the app.php line to your application entrypoint
for directory setup, yours is fine, just a couple of things:
your SDK tools are outdated, since you can download:
http://www.sencha.com/products/sencha-cmd/download/ (v3.0.0)
following docs at http://docs.sencha.com/ext-js/4-1/#!/guide/command you can get a "build" with the class you need, but in the end or you manually switch between development / production javascript file, or you switch using environments variables in your code.
Actually I think you could use a "fake" index.html in build directory to be modified by building tool then in production code you can mimic the code generated by sencha build.
Creating a index.html file to generate the project file will be a way to go. I also found that sencha architect is very rigid and hard to use. The most annoy thing is that I can't use the external editor to edit the generated code. Everything have to be done in the designer, which is fine if the designer can provide every functionality I need. But it can't.

Uploading images along with Google App Engine

I'm working on a Google App Engine project.
My app is working and looking correct locally, but when I try to upload images in an image directory, they're not being displayed at appspot.
As a little troubleshoot, I put a HTML page in "/images/page2.html" and I can load that page at the appspot, but my pages don't display my images. So, it's not a problem with my path.
As another sanity check, I'm also uploading a style sheet directory with .css code in it, and that's being read properly.
I have a suspicion that the problem lies in my app.yaml file.
Any ideas?
I don't want to paste all the code here, but here are some of the key lines. The first two work fine. The third does not work:
<link type="text/css" rel="stylesheet" href="/stylesheets/style.css" />
Page 2
<img src="/images/img.gif">
This is my app.yaml file
application: myApp
version: 1
runtime: python
api_version: 1
handlers:
- url: /stylesheets
static_dir: stylesheets
- url: /images
static_dir: images
- url: /.*
script: helloworld.py
You have to configure app.yaml for static content such as images and css files
Example:
url: /(.*\.(gif|png|jpg))
static_files: static/\1
upload: static/(.*\.(gif|png|jpg))
For more info check out:
http://code.google.com/appengine/docs/configuringanapp.html
I'll bet your problem is that you're using Windows.
If that's the case, I believe you need a preceding slash for your static_dir value.
I am using the Java version of App engine, and I faced a similar issues with the server not able to serve static images.
What worked ultimately was to change the AppEngine config file "appengine-web.xml" in my case to contain
<static-files>
<include path="**.*"/>
<include path="/images/**.*" />
</static-files>
My images are in the /images directory and HTML and CSS are in . directory which is at the WEB-INF level
#jamtoday The preceding slash didn't make a difference, but it did get me started figuring out what each app needs to be told what about my directory structure.
So, I have nothing very conclusive to add, but I wanted to follow up, because I got it working, but I didn't explore all the issues after I got it working.
One change that helped was to stop working from a HwlloWorld/src/ directory and start working in the HelloWorld/ directory. It seems like the dev_appserver picked up all the dependencies, but the remote server didn't. Essentially, the relative path of my local links didn't match the relative path of the links after uploading.
I also realized that the dev-appserver relies on the .yaml file, as well as the appcfg script. That is. . .if you add a directory to your project, and then try to link to files in that directory, you need to add the directory to the .yaml file, and then restart the dev-appserver to pick up on this.
So, there are probably ways to handle what I was originally trying to do if you give the .yaml file the right info, but changing to a different directory structure locally handled it for me.
<img src="/images/img.gif">
this line can't show you the image.
Try this one:
1-Create a class to handle "image request"
class GetImage(webapp.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'image/jpg'
self.response.out.write(image_object)
2-In your page.html:
<img src="/image"
3-At the main function in your code.py:
application = webapp.WSGIApplication(('/image', GetImage), debug=True)
have fun

Resources