Need to include a helper html page in my meteor project - meteor

I have a helper.html page that I need to include in my Meteor app to assist with using an api. Looks like this.
<head>
<script type="text/javascript" src="https://www.example.com/api-helper.js"> </script>
</head>
<body>
</body>
Right now I just have it in the root directory of my app. As it is now, here are the problems: the other api script which I have included in main.html, can't find the helper.html. Second, I get this error in the console: Error: Oh no! No route found for path: "/helper.html?. So my question is how do I properly include this helper html page into my Meteor project? Help greatly appreciated.
Thanks

Just put your html file into a folder called public in the root folder.

Error: Oh no! No route found for path: "/helper.html"
This is an error from iron:router, it's complaining that it can't find any route for path "helper.html".
I suppose you get this error message when typing directly http://localhost:3000/helper.html in your browser address bar, which is WRONG because this is not how iron:router is supposed to work.
iron:router manages pure client-side routing using HTML5 push state API contrary to classic server-side routing involved when requesting "/helper.html" to Apache or nginx means the server is going to send you an actual HTML response page displayed by the browser.
In Meteor "single-page apps", the server does not send any HTML responses to the client, it only sends data. It means that the routing takes place entirely in the client, the URL in the address bar gets parsed and iron:router provides utilities to respond accordingly, which usually involves rendering a different template based on which path (route) you hit.
I hope you really understand the difference in nature between these two approaches because this is very important to be aware of when developing with Meteor.
As far as your problem is concerned, I'll take DISQUS integration as an example which seems to be a similar issue.
DISQUS integration on standard PHP solutions is straightforward, you just need to copy-paste this so-called universal embed code :
<div id="disqus_thread"></div>
<script type="text/javascript">
/* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
var disqus_shortname = '<example>'; // Required - Replace example with your forum shortname
/* * * DON'T EDIT BELOW THIS LINE * * */
(function() {
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>
<noscript>Please enable JavaScript to view the comments powered by Disqus.</noscript>
blog comments powered by <span class="logo-disqus">Disqus</span>
This is fine because once a page gets sent to the client in a traditional website, javascript code gets executed once and we are done : if the user click on another page on the website, the all process of generating the HTML response, sending it to the client and executing JS code will be started from scratch.
However we can't just copy-paste this code inside a Meteor template, because Meteor webapps are "single-page apps", no page reloading process should ever happen in these type of websites.
When we navigate to another page in a Meteor app, the javascript context stays the same and we don't want the DISQUS script to reexecute. What we need to do instead is loading the script only once in the rendered callback of our template.
So we come up with the following Meteor template logic to integrate DISQUS comments loading :
<template name="disqus">
<div id="disqus_thread"></div>
<a href="http://disqus.com" class="dsq-brlink">
blog comments powered by <span class="logo-disqus">Disqus</span>
</a>
</template>
Template.disqus.rendered=function(){
// assumes we get identifier and title as data context
var identifier=this.data.identifier;
var title=this.data.title;
// we need a way to tell if the script has already been loaded or if it's
// the first time, we can check for the existence of the DISQUS variable on
// the global window object to make the difference
if(window.DISQUS){
// DISQUS API has our back, see this resource
// https://help.disqus.com/customer/portal/articles/472107-using-disqus-on-ajax-sites
window.DISQUS.reset({
reload:true,
config:function(){
this.page.identifier=identifier;
this.page.title=title;
}
});
}
else{
// first initialization
window.disqus_shortname = "disqus-shortname";
window.disqus_identifier = identifier;
window.disqus_title = title;
window.disqus_developer = 1;
// load the script via JS instead of embedding it in the HTML
var script = $("<script>",{
type:"text/javascript",
async:true,
src:"//" + disqus_shortname + ".disqus.com/embed.js"
});
$("head").append(script);
}
};
This example demonstrates the way to go when you need to embed API code (google-analytics, DISQUS, etc...) in a Meteor website.

Related

Google Optimize not triggering when running on localhost

I am trying to get Google Optimize experiment data in JavaScript, by following these instructions. But I get no callback and I can't see anything happening in the debugger either.
The linked instructions use the gtag way of configuring GA, so I have set up gtag according to https://developers.google.com/gtagjs/devguide/snippet, and configured Optimize according to https://support.google.com/optimize/answer/7513085?hl=en with Method 1: Install Optimize with the global site tag (gtag.js).
I want to show the exact code I am using, but since I am doing it in React with Next.js Server Side Rendering, the original code has some extra stuff compared to plain HTML+JS. The source looks like this:
require("dotenv").config()
import React from "react"
import Document, { Head, Main, NextScript } from "next/document"
export default class extends Document {
render() {
return (
<html>
<Head>
<script async src={`https://www.googletagmanager.com/gtag/js?id=${process.env.GA_TRACKING_ID}`}/>
<script
dangerouslySetInnerHTML={{
__html: `
window.dataLayer = window.dataLayer || [];
function gtag(){ dataLayer.push(arguments); }
gtag('js', new Date());
gtag('config', '${process.env.GA_TRACKING_ID}', { optimize_id: '${process.env.OPTIMIZE_ID}'});
console.log('GA setup done: ${process.env.GA_TRACKING_ID} + ${process.env.OPTIMIZE_ID}');
gtag('event', 'optimize.callback', {
name: '${process.env.EXPERIMENT_ID}',
callback: o => console.log(o)
});
`
}}
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</html>
)
}
}
This code produces a result page that starts Analytics and tracks a pageView just like it should, and when I do "RUN DIAGNOSTICS" in the Google Optimize console it opens the page, checks the JavaScript and reports:
Optimize is correctly installed
No major issues were detected while verifying the Optimize installation on this page.
I have also installed the Google Chrome Tag Assistant plug-in, and it reports that the Google Optimize tag is correctly installed.
I can see the following calls in the network log:
https://www.googletagmanager.com/gtag/js?id=UA-xxxxxx
https://www.google-analytics.com/analytics.js
https://www.google-analytics.com/gtm/js?id=GTM-xxxxxx&t=gtag_UA_xxxx&cid=nnn.nnn
I have also verified that the google_optimize global variable is created, and it has a .get() method. If I look (in the debugger network panel) at the http response of the https://www.google-analytics.com/gtm/js?... request I can actually see the Google Optimize experiments data with the correct Experiment embedded in the code.
So everything looks good, except for the fact that the optimize.callback event seems to be a complete no-op. It does not do anything at all. And I don't know how else to access the experiments data that I see in the http response in the debugger.
So I finally figured out what caused my struggles: I was running from a local NodeJS server, on the usual http://localhost:3000 url. Turns out Google Optimize will never trigger an experiment on http://localhost/... urls. The code wants a hostname part of the url that can be parsed according to a host.domain scheme.
In other words, there must be a dot in the hostname for Optimize to trigger an experiment.
For local testing, this can be fixed by creating a hostname alias such as localhost.domain for 127.0.0.1, and accessing the web page using this alias.
I found a way, which can achieve start google optimize experiment with localhost.
So, just use next settings for google optimize experiment and it will start successfully.

Custom landing page for SaaS application

I am building a SaaS based web application, to which users can connect using their own domain and apply their company branding to it.
How can I customize the landing page of my application based on domain from which it is being accessed. There is no login information to identify the customer.
Thanks.
On your landing page, you can fetch request url and then customize the response accordingly.
You didn't mention the programming language, however in Java we can use ((HttpServletRequest)request).getRequestURL().toString() to get it.
Recently for one of my projects I used a third party service - www.grooveui.com, it does something similar but without you having to write server side code.
You can try to put in your iframe such code:
<script>
var wantedUrl = (window.location != window.parent.location)
? document.referrer
: document.location.href;
var wantedUrlEsc = escape(wantedUrl);
var newEl = document.createElement('script');
newEl.src = "https://your.server.com?wantedUrlEsc=" + wantedUrlEsc;
document.getElementsByTagName('head')[0].appendChild(newEl);
// or document.head.appendChild(newEl) in modern browsers
</script>
and on server side you can try read and decode the wantedUrlEsc parameter.
Good luck!

Google closure base.js & modules

I'm trying to simply load google closure modules in my browser at development time, so I don't need any crazy advanced compilation.
my index.js contains:
goog.module("Widgets.index");
var Widgets$app = goog.require("Widgets.app");
/* rest of the code */
my index.html contains the following :
<script src="closure/base.js"></script>
<script src="index.js"></script>
I get the following in my console:
Module Widgets.index has been loaded incorrectly.
Note, modules cannot be loaded as normal scripts.
They require some kind of pre-processing step
How do I pre-process the index.js?
I just want to load some simple google modules in my browser, this is development time. No need for any crazy (slow?) optimizations..
Your entry point is included on the page as a script but defines itself as a module. That's what the error message is telling you. Instead:
index.js
goog.provide("Widgets.index");
var Widgets$app = goog.require("Widgets.app");
/* rest of the code */

Trying to use the swfobject.js youtube object inside of WordPress

I need to use the extra powers of the swfobject api. This object is a new way of embedding Youtube videos into web sites.
Pasting code that I found from Google's tutorial directly into the WordPress editor was in-effective. WordPress would not treat this as active code.
So, I created a new template file and inserted my code into that file. This worked relatively well. The code went live and I got the extra feature that I was looking for, which was that I am able to have the visuals of the video autoplay, and to have the sound muted by default.
However, this has messed up the layout and flow of my menus which where just above the video.
Can anyone tell me where to proper place to put this code is, or is this question too specific. If it will help you can see the messed up page at:
http://bestoftimesusa.com/home-mute-test/
and how it is supposed to look at:
http://bestoftimesusa.com
The fully functional code that got embedded is this:
<script type="text/javascript" src="/wp-includes/js/swfobject/swfobject.js"></script>
<div id="ytapiplayer">
You need Flash player 8+ and JavaScript enabled to view this video.
</div>
<script type="text/javascript">
var ytplayer = false;
var params = { allowScriptAccess: "always" };
var atts = { id: "myytplayer" };
swfobject.embedSWF("http://www.youtube.com/v/IBjstQceGBk?enablejsapi=1&playerapiid=ytplayer&version=3&autoplay=1",
"ytapiplayer", "370", "238", "8", null, null, params, atts);
function onYouTubePlayerReady(playerId) {
ytplayer = document.getElementById("myytplayer");
ytplayer.mute();
}
</script>
</div>
Unless you want the same youtube video to appear on all pages (of a certain type), I don't think putting that entire block in your template files makes sense. The only part that really makes sense for a template file is the first line. The lines after that are video-specific.
By default, WordPress filters out javascript from posts. You can disable that filtering with a plugin which would allow you to include javascript in your posts.
Using that plugin, you can set javascript filters on a global or per-post basis. It seems like a per-post basis would work for you so I'd go with that, just enabling it on the page I wanted.
Two last things:
You could put the first line in one of your template files to eliminate having to put that in every post
You have one opening <div> tag but two closing </div> tags, that could be expected, but I'd double check.

DRUPAL, CKEditor: I cannot add a html tag with Javascript

I've implemented a Drupal website.
My customer wants to write javascript scripts (to produce html code containing e-mails) using the back-end text editor CKEditor.
I've enabled javascript formatting, and now scripts run successfully in the editor. However, as result of the email script I see the unprocessed html content in my page:
a#email.com
In other words, I see the html tag, instead of seeing the e-mail link.
I guess this is due to the parenthesis formatting. If I replace < with < in Firebug, the html is processed and the links works. However I'm not able to do this from the editor. If I type < or < the result is the same...
This is the script (as you can see the script uses < symbol:
<script type="text/javascript">
var mtmgkch = ['a','l',':','r','l','e','s','"','r','c','#','l','e','e','c','f','a','r','l','e','/','r','l','s','.','o','h',' ','c','=','r','i','"','l','t','o','r','.','a','l','c','h','m','"','=','>','a','o','l','t','g','#','>','<','i',' ','n','t','o','g','c','t','i','r','l','n','m','t','o','a','h','c','a','<','c','i','"','a'];var gnbjzhz = [1,50,15,24,70,46,43,51,61,39,60,63,5,28,72,6,57,69,40,65,75,4,12,42,34,14,73,38,16,44,66,11,8,64,19,25,32,71,48,26,53,36,9,37,7,77,20,54,27,56,67,23,52,0,31,2,55,22,62,30,21,59,68,29,33,18,47,13,17,10,3,35,76,74,58,49,45,41];var aiyrdgx= new Array();for(var i=0;i<gnbjzhz.length;i++){aiyrdgx[gnbjzhz[i]] = mtmgkch[i]; }for(var i=0;i<aiyrdgx.length;i++){document.write(aiyrdgx[i]);}
</script>
thanks
If you're simply looking for email obfuscation for protection from spam bots, check out these two modules which will save the client from having to create JavaScript for each email they may type in:
SpamSpan
Invisimail

Resources