Static HTML written by meteor js? To embed in an <iframe> - javascript

Disclaimer - I am very new to making web apps, I just went through a few meteor js tutorials over the weekend, it's pretty cool.
I have this project I want to make, which involves embedding tabular data into websites. I want to do this with a iFrame.
I can see how this could be done with meteor, route to a template to render out the html I want, but I'm concerned with performance. Having the whole app load up to just display a few lines of html seems excessive, it certainly doesn't need all the javascript.
The html can be a static file, only changing when the web app user saves a change, it doesn't have to dynamically load every-time somebody sees the embed.
So what I'm really asking is, how can I use meteor js to write a static html file?

What you need is server side rendering (SSR), because you are intending to serve html directly from your meteor server.
Meteor does not support SSR, yet.
While I haven't myself tried to get SSR working in meteor, Arunoda has, ableit some rather severe limitations. Basically you cannot have much reactivity there. This is probably due to the use of fibers on the server. But you said you do not need reactivity anyway in your iframes, so that should not stop you.
You can combine Arunoda's solution with Iron Router's server routes.
Enable the SSR package:
meteor add meteorhacks:ssr
Put your template into the private directory:
<!-- private/embed.html -->
<template name="embed">
<ul>
{{#each posts}}
<li>{{title}}</li>
{{/each}}
</ul>
</template>
On the server, compile it with:
SSR.compileTemplate('embed', Assets.getText('embed.html'));
And declare your template manager:
// server/embed.js
Template.posts.getPosts = function(category) {
return Posts.find({category: category}, {limit: 20});
}
And then add a server-route as follows:
Router.route('/embed/:owner', function () {
var html = SSR.render('embed', {owner: this.params.owner});
this.response.end(html);
}, {where: 'server'});
Now you just need to point your iframe to http://localhost:3000/embed/myusername.
At this stage I would not recommend using meteor in this way, but instead create a simple backend that connects to DDP or mongo directly and renders your iframe's html.

Related

Export Vue dynamic site to Static HTML on run time

I am trying to generate/export the html/css from a Vue Application to a static index.html and the css assets without the script I wrote within the vue app which makes calls to the internal servers.
Use case:
An employee creates a digital Information site about a car of the company.
Here he needs to enter vehiclenumber etc, it then makes a GraphQL query with these parameters to our internal server.
Once the information loaded and is filled in on the site, an option should be given to "Save" (Export) the html/css with only the necessary js for vue components itself to work (e.g. Element vue gallery)
The Employee creates the page using localhost:8080?carnumber=xxx&info=xxx
The Server queries itself should not be included as they will be unreachable from outside the intranet.
So I want the static html to not care about the route and parameters and display the HTML as seen on localhost:8080?carnumber=xxx&info=xxx
I have looked for "static site generators" etc but I have not come across a result I am looking for as the page itself isn't static only the export should be. I also came across Nuxt.js but not exactly how I want it to be, the best would be to have it call like a NuxtGenerateStaticPage(this) function (in my dreams)
Please let me know if anything is unclear.
I appreciate any input/idea :)

Integrate React components into an existing NET Core app

I have an existing application build with .Net Core Framework. I would like to integrate React components for re-usability purposes which at this point will only be app specific. I have gone through numerous "Hello World!!" tutorials but that doesn't satisfy my need. I have also looked at reactjs.net but that also is not going to help me as the components gets rendered on the View
Scenario
Application has lots of Modals with a form which gets rendered on numerous pages. Currently it is being handled with JavaScript. The JavaScript code gets duplicated a lot to achieve it.
Goal
Would like to have a react component to replace above mentioned functionality to reduce code getting duplicated.
The problem I am facing is I am not sure how will I be able to interact with the component from a jQuery/JavaScript point of view.
Example
I have a DataTable and one of the actions is to click on a certain button to display the Modal. The code is in a separate .js file so it is separate from the View. So in this case if I click on a button I would like to render the react component. I would need to pass props through to the components and that is where I am uncertain how would I handle it :-(
Any suggestion or guidance would be appreciated.
Thanks in advance
Using react in Asp.Net Core application is easy. At first you need to know your back-end will be API based to communicate with react. So if you have not set up your Core application to an API based, it won't work. Also make sure you have installed nodeJs and other dependencies.
To get started with react, create a new folder in your Asp.Net project solution.
Open the folder in your Command line and execute:
npx create-react-app [your--folder--name]
To view your created app, run
npm start
To get started with asp.net, you need to add spa dependencies in your project.
Then you have to set up your ConfigureService method to include:
services.AddSpaStaticFiles(configuration => { configuration.RootPath = "[your--folder--name]/build"; });
Finally set up your Configure method to include:
app.UseSpaStaticFiles();
app.UseRouting();
app.UseEndpoints( ... );
app.UseSpa(spa => {
spa.Options.SourcePath = "[your--folder--name]";
if (env.IsDevelopment()) {
spa.UseReactDevelopmentServer(npmScript: "start");
}
});

Combining react and jade

I am working on an isomorphic javascript app with express + react. We started out using jade for server side templates for static content, but combining the two is quickly becoming unwieldy. We have ended up with something like this:
In the express routes:
router.get("/", function(req, res) {
var webpackStats = require('../../config/webpack-stats.json');
var reactHtml = React.renderToString(HiwApp({}));
var slideshowHtml = React.renderToString(slideshowApp({}));
var config = {
webpackStats: webpackStats,
reactOutput: reactHtml,
slideshowHtml: slideshowHtml
};
res.render("how_it_works/howitworks", config);
});
In Jade:
body
.company-logo.center
#react-main-mount
!= reactOutput
include ./content_block_1.jade
include ./content_block_2.jade
#slideshow-main-mount
!= slideshowHtml
This is very brittle-if we want jsx then a jade template then more jsx, we have to make sure we get the order right.
My idea is to do it all with jsx. I know there is React.renderToStaticMarkup for this sort of thing, but that doesn't solve the problem of mixing dynamic with static pages.
The big questions: if we decide to do all of this with jsx (say layout.jsx which contains all components), then call React.renderToString(App({});, will this be a major performance hit? If so, is there a better way to do it to easily combine static and dynamic blocks?
Although this may be a tiny bit off topic: We stuck with jade templates.
Basically we wanted the flexibility to use a non-react + flux architecture for areas of the site when and if that need arose. Our site is basically made up of a number of smaller SP apps: Site, UserAccount, Team and Admin.
Why did we do this?
Smaller filesize and overhead for users who are not accessing all sections of the site.
Option to "opt out" of React and flux if and when the need arises.
Simpler, server side authentication.
The way we have done it successfully was to render a JSX shell template (Html.jsx) on the server using React.renderToStaticMarkup() and then send it as the response to every server-side express route request that is meant to deliver some HTML to the browser. Html.jsx is just a shell containing html head information and GA scripts etc. It should contain no layout.
// Html.jsx
render(){
return (
<html>
<head>
// etc.
</head>
<body>
<div
id="app"
dangerouslySetInnerHTML={{__html: this.props.markup}}>
</div>
</body>
<script dangerouslySetInnerHTML={{__html: this.props.state}</script>
<script>
// GA Scripts etc.
</script>
</html>
)
}
Remember it is totally fine and even recommended to use dangerouslySetInnerHTML on the server when hydrating your app.
Dynamic layout should be done with your your isomorphic components through a hierarchy of components based on their state/props configuration. If you happen to be using React Router, then your router will render view handlers based on the routes you provide it so that means you don't need to manage that yourself.
The reason we use this technique is to architecturally separate our "App" which is isomorphic and responds to state from our server-side template shell which is just a delivery mechanism and is effectively boiler plate. We even keep the Html.jsx template amongst all the express components within our app and do not let it mix with the other isomorphic React components.
One of the most helpful resources I found for working out React/isomorphic architecture was https://github.com/yahoo/flux-examples/tree/master/react-router which is where we stole this technique from.
We explored the idea of integrating handlebars as a templating engine for client's devs using our products in the future but decided that it was less complex to write our own DSL in JSX and use some simple parsing routines to parse our HTML-like DSL to JSX by adding things like export default (ES6 module syntax) at the start of the template and then import the template to a rendering component.
You could of course follow that line of thought and use a jade compiler to spit out the template and then add module syntax around that if you think separate jade files are essential. I also noticed this project as well although I have not explored it in anger: https://github.com/jadejs/react-jade.

Lazy Loading templates in Meteor

I use require.js to do lazy loading for a Javascript app. I would love to switch to a meteor stack but right now it looks like Meteor sends the whole app (all the templates) through on the initial load. Has anyone had success with require.js and meteor or any other implementation?
You're asking different questions, but certainly they are connected. The first is about loading additional javascript code into your meteor app. Of course you can use thing like requirejs. This should work fine supposing your lazy code is located in the public directory of your meteor project. However, my experience is that requirejs goes mad when the contents of public gets updated often, so for example in the development environment. Maybe it's a matter of customizing the library, but I would rather recommend using some lightweight homebrewed package. Look here, if you need some inspiration.
The second question is about lazy template definition. Each template consists of two parts. The first is its html code, written in handlebars syntax, the second is all the javascript code which you write to define how your template should behave (e.g. helpers, event handlers). The second part is easy, as long as we assume that we already know how to load the lazy code (see the above paragraph) and the template, lets call it myLazyTemplate, is already defined, so basically speaking Template.myLazyTemplate is not undefined. So how to achieve the latter?
To dynamically define a new template you'll need to call
Template.__define__(name, raw_func)
on the client. So the last question is "what is raw_func?". This is a compiled version of your html code which is normally created automatically on the server and then sent down the wire to the client when the app gets loaded (look here to see how it's done in meteor). But we want to do it dynamically, right?
So the idea is to compile the template code manually with a help of the Handlebars.to_json_ast routine. You can feed it with your template html code, and the output is some javascript array that can be sent to the client anytime by the method we've already talked about. The last thing you need to do is to call Handlebars.json_ast_to_func on the client, using the data sent from the server as the only argument. The output produced by Handlebars.json_ast_to_func is the raw_func you can use to produce myLazyTemplate template.
I'm aware that this is only a rough idea, not the whole solution to your problem. I hope this will help you to figure out the final solution on your own.

what is the best architecture to show the frontend of a pure js app?

Basically, if you have a purely JS app (that get info from socket.io, or from a server with ajax request), and you need to show this data after processing it, what technique are you using?
Currently i'm creating the elements manually with code like
var myDiv = new Element('div',{ /* options */);
And injecting it where I need making all the DOM structure. I find this hard to maintain and especially for those designers that can code html, but they can't code html from JS.
Is there any way that will improve this process? Is it better to get the html from ajax? or just make html code in a string?
I'm looking for the most optimal in terms of maintenance and resources.
What you're looking for is a "template".
You have an HTML template (some divs, etc) and you bind this with the datas you provide in JS. Then, with whatever template engine you're using, you can get the full HTML.
Here are some template engines out there:
https://github.com/flatiron/plates
http://embeddedjs.com/
And a code sample using plates:
var Plates = require('plates'); // specific to node.js, see for client-side use
var html = '<div id="test">Old Value</div>';
var data = { "test": "New Value" };
var output = Plates.bind(html, data);
console.log( output ); // '<div id="test">New Value</div>'
You can store your templates either in a single file ("templates.html") loaded through ajax, or by storing it in the HTML page (not really recommended for maintenance matters).
If you store them all in an external file, you can do something like this:
templates.html:
<!-- text/html isn't parsed by the browser so we can put anything in it -->
<script type="text/html" id="template1">
<!-- put your template in there
</script>
And you can get its content through getElementById( 'template1' ).
Easiest way for you if project is in late stage to add something like jQuery.template plugin and create templates in separate files. Then, use backend to combine those peaces in single page and on DOM Ready fire up your client side app.
If your project is in early stage use AngularJs or BackboneJS frameworks. Believe me it is worth every cent :)
I would recommend you take a look at Backbone.js.
Backbone.js gives structure to web applications by providing models
with key-value binding and custom events, collections with a rich API
of enumerable functions, views with declarative event handling, and
connects it all to your existing API over a RESTful JSON interface
I use backbone even if I am not over a RESTful interface. It's pretty easy to separate the structure from the behavior ... You can achieve the same using jQuery but it wont be as neat and clean. It's one of the MV* framework. You have:
Models containing the interactive data as well as a large part of the logic surrounding it: conversions, validations, computed properties, and access control.
Collections are ordered sets of models.
Views: The general idea is to organize your interface into logical views, backed by models, each of which can be updated independently when the model changes, without having to redraw the page
Routers provides methods for routing client-side pages, and connecting them to actions and events
It's getting attention recently. Apps that were created using Backbone include:
FourSquare
LinkedIn for Mobile
This is a great resource if you're starting to work with Backbone.
Distal Templates http://code.google.com/p/distal/ :
<table id="a">
<tr><th>OPINIONS</th></tr>
<tr data-qrepeat="m keywords"><td data-qtext="m.name"></td></tr>
</table>
Then call:
distal(document.getElementById("a"), {
keywords: [
{name:"Brilliant"}, {name:"Masterpiece"}, {name:"Witty"}
]
});
will become:
<table>
<tr><th>OPINIONS</th></tr>
<tr><td>Brilliant</td></tr>
<tr><td>Masterpiece</td></tr>
<tr><td>Witty</td></tr>
</table>
And injecting it where I need making all the DOM structure. I find this hard to maintain and especially for those designers that can code html, but they can't code html from JS.
Another option is modest. As you can see from the documentation, it obviates the need for HTML chunks in javascript. The designers can change the HTML structure without needing to look at the javascript, and javascript coders can use parameters defined by the designers to fill in the data (all in javascript).
This example is from the readme:
HTML:
<div>
<contact>
<name>Casey Jones</name>
<phone>123-456-7890</phone>
</contact>
</div>
Javascript:
var contact = {
name : "Casey Jones",
cell : "123-456-7890"
};
var out = modest.render('contact',contact);

Categories