Register a Javascript with a different mime type with Plone - plone

I have a Plone product for integration of MathJax; because the usual way of reading everything from the cdn network doesn't work well for me, I forked https://github.com/collective/collective.mathjax to use the packaged MathJax. (I also don't like to have a script reference with a query string on every page, while most of them not even contain formulas).
However, according to MathJax documentation: Using in-line configuration options, I should better have a configuration script with a text/x-mathjax-config mime type. From the looking at it, adjusting the mime type seems not to be possible in the Javascript registry.
So, how can I register a resource with a customized mime type? Or do I need to build the script element manually?

You can store MathJax configuration blocks in regular JavaScript elements.
This is documented on the docs page you linked to (just a little further down).
To quote:
Starting with MathJax version 2.3, it is possible to set window.MathJax to a configuration object in any Javascript code before MathJax’s startup. MathJax will then use that object for its initial configuration. For instance the previous example becomes:
<script type="text/javascript">
window.MathJax = {
tex2jax: {
inlineMath: [ ['$','$'], ["\\(","\\)"] ],
processEscapes: true
}
};
</script>
<script type="text/javascript" src="path-to-MathJax/MathJax.js?config=TeX-AMS_HTML">
You can put this kind of configuration into a separate file as well; just make sure you load the configuration before MathJax. If you want to load it via the query string on MathJax.js, then make sure to follow http://docs.mathjax.org/en/latest/configuration.html#using-a-local-configuration-file-with-the-cdn

Related

Next JS Version 12+: Static Site Generation

I'm using Next.js version 12.0.4 on a new project, having used Next.js version 10 on a prior one.
Has something changed with Static Site Rendering at build time? It's rendering all my output pages when I do an npm run build (which in turn executes "next build and next export") with html files that include a ton of .js files and no native text "content" which I'd expect.
That is, the output doesn't have any of the standard HTML <h1>, <h2> etc. in it, just a bunch of javascript for the client to hydrate.
Prior versions of Next.js (or perhaps it was my configuration?) seemed to render pure, finalized HTML just fine.
I'm trying to render a simple About page (no dynamic routes, no dynamic props for this route) and, while it properly renders a page in the "/about/index.html" output location, that page has a bunch of .js files and a JSON payload. That page does indeed display properly, but I'd really like the output in the "out" directory to be actual .html files with HTML pre-rendered, for SEO and other reasons.
In my next.config.js, I've specified:
module.exports = {
exportPathMap: function () {
return {
"/": { page: "/" },
"/about": { page: "/about" },
};
},
};
I've also specified getStaticProps on the about page conponent (about.tsx). (I'm using typescript if that matters.)
The rendered /about/index.html file has a ton of .js includes and no real HTML "content".
Have I missed a configuration setting? What can I do to make it render pure HTML where I'd like?
AHA! Ok, so this error was of course a coding error on my side.
In _app.tsx, I had a wrapper for Authentication that I had written. By (bad) design, it was deliberately NOT rendering children for it if the user wasn't authenticated. Therefore, the pre-renderer wouldn't render the "regular" html elements, because the pre-renderer of course does not sign in.
If this same problem happens to you, make sure you're not wrapping all views up in some provider element which conditionally renders children.

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 */

Do I need less.js if I'm using dotless?

I'm trying to import a bootstrap/angular (made for node)/less theme my company purchased into a ASP.net MVC project from scratch.
The theme uses less, so doing some google searches, I installed "dotless" and "dotless adapter for System.Web.Optimization".
So I'm copying and pasting the references and it errors here:
<!-- prochtml:remove:dist -->
<script type="text/javascript">less = { env: 'development' };</script>
<script type="text/javascript" src="~/assets/plugins/misc/less.js"></script> <-- Errors Here
<!-- /prochtml -->
It says "LessCssHttpHandler.cs not found". "You need to find LessCssHttpHandler.cs to view the source for the current call stack frame."
I was looking into what "less.js" does.. and i couldn't find a clear cut description but it seems like it makes it so that you're able to use the LESS environment because CSS isn't a current standard like CSS is.
If i'm right in my assumption, do I not need to include "less.js" into my project? Thanks
No. Once the processing is done server-side (using dotLess), no need to include Less.js in the client-side (as data is already received as regular CSS).
Also, if you're using Visual Studio, you can set WebEssentials to automatically compile your Less files upon saving (SomeStyleSheet.less -> SomeStyleSheet.css), then on the client-side you're simply loading regular CSS. That will spare you from both server and client side compilation needs.

Returning razor-parsed Javascript as a ViewResult from a controller

I've successfully created an mvc/razor web application that returns css files that have been parsed by razor. Each time there's a background-image I have a razor snippet that writes the URL prefix to the image file name. The CSS now looks like this:
body { background-image: url(#LookupUrl.Image("background.gif")); }
Css files now work fine and I've moved onto trying to get javascript .js files to function the same way but these aren't playing ball.
The code is identical to the css code and it successfully finds the .js file, but razor seems to parse it differently. Here's an example js file:
function testFunction() { alert('test function hit!'); }
testFunction();
Razor seems to think it's code that it should compile, and gives the error:
Compiler Error Message: JS1135: Variable 'alert' has not been declared
> Source Error:
>
> Line 1: function testFunction() {
> Line 2: alert('test function
> hit!'); Line 3: } Line 4:
> testFunction();
After renaming the same file to .css it works fine.
Is there a way of getting razor to function with .js files in the same way as it does for .css?
Here's how I registered the file handlers for razor:
RazorCodeLanguage.Languages.Add("js", new CSharpRazorCodeLanguage());
RazorCodeLanguage.Languages.Add("css", new CSharpRazorCodeLanguage());
WebPageHttpHandler.RegisterExtension(".js");
WebPageHttpHandler.RegisterExtension(".css");
The build provider is registered in PreApplicationStart via the method Haacked outlines in his blog post.
Do I need to remove a handler that mvc adds for .js files?
UPDATE 2 days on
While I got working what I wanted to get working, I would not recommend this method to others. Using Razor to parse css/javascript is flawed without the use of <text><text/> - it's the simplicity of razor using the # ampersand that messes it up. Consider the CSS3 #font-face. Razor hits the # and thinks it should use it as a function. The same thing can happen with javascript, and happened with Jquery 1.5.1.
Instead, I'll probably go back to aspx webforms for dynamic css/javascript, where there's less chance of the <% %> code blocks appearing naturally.
I couldn't understand why CSS worked while JS didn't, especially after the copy+pasted JS code worked inside the CSS file.
I used the find/replace dialogue within visual studio on the System.Web.WebPages.Razor source to search for the string '.js' within the project. There was nothing helpful there so I then went to the System.Web.WebPages project. It found a match in System.Web.WebPages.Util, which is a static class with a few helper methods.
One of those methods is 'EnsureValidPageType' and within there is a try/catch block. Inside the 'catch' block is a comment:
// If the path uses an extension registered with codedom, such as Foo.js,
// then an unfriendly compilation error might get thrown by the underlying compiler.
// Check if this is the case and throw a simpler error.
It made me believe .js has got some special built-in handler with it.
I googled for a bit, couldn't find anything, then looked in the web.config that's within \Windows\Microsoft.NET\Framework64{version}\Config.
In there is a buildProvider mapping for the extension .js to
System.Web.Compilation.ForceCopyBuildProvider
After removing this buildprovider in the website's web.config, .js files get compiled and work as they should!
I'm still not too sure what the ForceCopyBuildProvider does or is for but I wonder if it's for visual studio. Various extensions have different Copy/Ignore build providers registered.
Once again apologies for answering my own question but I hope the comprehensive(waffley) answer might help others out.
You could try using the special <text> node to indicate to the Razor parser to treat the content literally:
<text>
function testFunction() { alert('test function hit!'); }
testFunction();
</text>
The default Razor parser uses the HtmlMarkupParser to handle the markup components of your template. There isn't currently any alternative parsers that support other markup languages (which you would need to treat the javascript code language as). If you did create a new markup parser, I would imagine it would be quite difficult to separate the code and markup (i.e. the C# and the Javascript).
What you could do, is use the <text></text> wrapping elements to enforce the parser switches to markup mode when that section of the template is reached, e.g.
<text>function testFunction() { alert('test function hit!'); }</text>
It's not pretty, but it should do the trick.

Google Fonts CSS Include

Hey,
Since Google Fonts came out, I have had this question in mind. First see this below:
<link href='http://fonts.googleapis.com/css?family=Cantarell&subset=latin' rel='stylesheet' type='text/css'>
Here Google is linking to an external CSS file that doesn't have a file extension (.css)! Then Google also has another feature that if you want to inlude another font to this then just add the "|" sign and type the font name. How do you do this? Using Javascript, PHP or something?
Help is appreciated!
Thanks :)
The extension of a file does not have to mean anything at all about the contents of said file. It is merely a convention (one that Windows, for instance, uses to the point of making it seem like a requirement).
Any dynamic 'file' on a web site can return what ever kind of content it wants, any time it wants. The extension means nothing - aside from expected convention.
That URL could be a directory named css with a default 'document' that is a script, which handles the parameters to decide what content to give. Or, it could be a literal file named css which does the same thing. Or, it could not be a file or folder at all, instead merely part of a routing mechanism, which calls a controller based on the URL, and passes the parameters in.
Web servers return information in the response indicating what the MIME Type of the return value is, and the browser determines what to do with it based on that - not based on the extension of the file.
Yes, they have to be doing some sort of server-side processing when this URL is requested
http://fonts.googleapis.com/css
The querystring is parsed, and a text stream is returned with the CSS output. Allowing the user to add additional font families to the CSS is pretty trivial, as the server is just spitting back what you append to the query string.
You could do this in PHP or ASP.Net (and many others), but there is no indication of the underlying technology from Google's URL.
The easiest way to do this yourself would be to create a folder on your web server called "css", and then have a default script in there that does the processing. The URL could basically be almost identical to the Google url.

Resources