I'm using includes in my extension.js file and want to be able to nest other include files. For example: I want to include a file 1.js which in turn includes 1-1.js and 1-2.js, and then 1-2.js includes 1-2-1.js and 1-2-2.js. I can use appAPI.resources.includeJS to include one level of files - but I can't seem to use it inside a resource file.
Also, why can't I just directly include files outside of the appAPI.ready callback? i.e. by simply concatenating the JS files.
To answer your second question first, you do not have to use appAPI.resources.includeJS to include JavaScript files and can in fact concatenate all your include files into one file. However, since the file can grow quite quickly, this is not recommended as there is a 150K limit per file.
Regarding nesting include files, this is certainly possible. Take the following example based on your question:
extension.js:
appAPI.ready(function($) {
appAPI.resources.includeJS('1.js');
});
1.js:
console.log('1.js loaded, now loading 1-1.js & 1-2.js');
appAPI.resources.includeJS('1-1.js');
appAPI.resources.includeJS('1-2.js');
console.log('Done');
1-1.js:
console.log('1-1.js loaded');
1-2.js:
console.log('1-2.js loaded, now loading 1-2-1.js & 1-2-2.js');
appAPI.resources.includeJS('1-2-1.js');
appAPI.resources.includeJS('1-2-2.js');
1-2-1.js:
console.log('1-2-1.js loaded');
1-2-2.js:
console.log('1-2-2.js loaded');
The result in the console:
1.js loaded, now loading 1-1.js & 1-2.js
1-1.js loaded
1-2.js loaded, now loading 1-2-1.js & 1-2-2.js
1-2-1.js loaded
1-2-2.js loaded
Done
[Disclosure: I am a Crossrider employee]
Related
Situation
I retrieve data from a CSV-source using the external data-extension for mediawiki:
{{#get_web_data:url=http://example.com/names.txt|format=csv|data=name=1}}
{{#display_external_table:template=AddCat|data=1=name }}
The file names.txt simply contains names, one per row.
The template AddCat simply adds the first parameter as category: [[Category:{{{1}}}]]
Problem
The page I use this template on actually shows the name-categories on its bottom but the page itself is not visible on the category-page (I ran the jobs of course).
I assume that this has something to do with the fact that the category-name is not present in the wiki-text but is fetched from an external source.
Any suggestions how I can really add the categories?
The extension has been extensively re-factored since you posted this quesion. The current version adds the page to the categories, in your example, immediately; I've checked.
I recommend that you upgrade the extension and MediaWiki.
Have you looked in CategoryHook?
CategoryHook to which you can add auto-categorisation rules to LocalSettings.php (after including CategoryHook.php--see #Installation). Following is an example which adds articles to Category:Articles containing trees if they have any {{#tree:...}} parser functions in their content.
$wgHooks['CategoryHook'][] = 'wfCategoriseTrees';
function wfCategoriseTrees(&$parser,&$text,&$categories,$sortkey) {
$categories['Articles containing trees']
= array(preg_match('/\\{\\{#tree:/i',$text),$sortkey);
return true;
}
There are several extensions, you may want to try this one
I don't really understand how the wrapper works. I understood the example of the catalyst tutorial but I don't know how to apply specific CSS file for a specific template.
Should I use [% IF %] statement in my wrapper.tt in order to select a specific template ? Do I call the CSS file with stash, like I do for a template in the controller ?
Some examples or hints would be great, thanks
You can certainly assign the CSS file to a stash variable in your controller.
sub frobnicate :Local {
my ($self, $c) = #_;
# ...
# this would probably be implied, i.e. in a properly configured Catalyst
# you don't have to actually set this, it will just load the right thing
$c->stash->{template} = 'frobnicate';
# this one is for loading the right CSS
$c->stash->{css_file} = 'frobnication.css';
}
And then in your TT wrapper, possibly wrapped in [% IF css_file %]...[% END %]:
<head>
<link rel="stylesheet" href="[% css_file %]">
</head>
That would work, but it is not good practice, because you are breaking the separation of concerns. The way the page looks should have nothing to do with your application controller.
You could also just load each CSS file whenever it's needed, but that is bad practice too, because it will impact page load times and the order in which things are loaded. Typically one puts CSS at the top in the <head>, and most javascript files at the end of the page, just before the </body> so that there is already content rendered before the browser goes off and fetches and runs javascript.
A more flexible, but also more complex solution is to write a method in your View that can be exposed as a TT vmethod to the Template Toolkit, and use it to add CSS files to the stash when needed. You can do that with expose_methods.
package MyApp::View::TT; # or whatever you have called this
# ...
expose_methods => [qw/add_css_file/],
# ...
sub add_css_file {
my ( $c, $self, $css_file ) = #_;
push #{ $c->stash->{_css_files} }, $css_file;
return;
}
Now you can use that in your template files. You can have a block at the very top or very bottom of each file to add CSS files to the list of files that should be loaded right where they belong to logically.
<h1>Order Confirmation</h1>
[% add_css_file('confirmation.css') %]
In your wrapper, you can iterate that list of files and load each of them. As you can see this approach comes with the benefit of allowing you to have more than one file.
<head>
[% FOREACH file IN _css_files %]
<link rel="stylesheet" href="[% file %]">
[% END %]
</head>
They'll be available in the stash because the wrapper gets rendered after the inner part of the page, but you can't do it from the template directly, because you cannot change the stash within Template Toolkit. If there are no files, this will not do anything because the loop has nothing to iterate over.
Note how I called the stash key _css_file. The underscore _ indicates that it's meant to be a private variable. Perl has no concept of private or public, but that's a convention to tell other developers not to mess with this.
It would be advisable to now add a second method to the View to read the list and return it. That would decouple the implementation detail of how the list of files is stored completely from the template. You could change it entirely without having to touch the template files at all.
If you have that exposed method, it would be smart to for example make sure that each file is only included once, e.g. with List::Util::uniq, or by using a hash and accessing the keys instead of going for an array.
I originally used this approach for javascript files rather than CSS. For CSS in your application I actually believe it would be smarter to condense all the styles into one file, and minify it. Your users will download most of them anyway, so why have the overhead of loading multiple files and making each initial page load a little bit slower, and blowing up their cache, if you can just have the very first page load be a tiny bit longer and then read everything from cache?
I've installed particle.js in my project and it works with the default effect, I have gone through this site http://vincentgarreau.com and found 5 effects: default, snow, NASA, Buddle and Nyan cat. My question is how can I use those effects in my project? I choose one and I downloaded the JSON config but I don't know how to add it to my project.
You just need to load the json file. The syntax would be something like this
<script>
particlesJS.load('particles-js', 'particles.json', function(){
console.log('particles.json loaded...');
});
</script>
Write the appropriate path if these files are located elsewhere. The 'particles.json' file will be your config file you downloaded from somewhere. You can even edit the particles.json file yourself to get your desired result.
This video by Traversy media is a great reference if you wish to dig deep into particle js and create your own desired effects.
Good luck!
https://www.youtube.com/watch?v=qK3cgD09Qf0&t=1567s
I'm developing a module where I've some custom js functions to be use in a form inside a Dialog.
I successfully loaded as inline script in the view that launch the dialog that include the form with something like:
$script = <<< JS
var scheda=$("table#schedaTable");
var idtum=scheda.attr('idtum');
scheda.find("i.modifica.concessione").on('click', function() {
$("#concessioneDialog").load("/cimiteriale/concessioni/edit-concessione?idtum="+idtum).dialog("open");
});
JS;
$this->registerJs($script, $this::POS_END);
but for several reasons I prefer to use an external file published in assets so my question is:
Is it possible to publish an external js file with MyModuleAssets.php and register it later in the view independently from the other js assets, where needed?
In fact I need to close and reopen the dialog with other ids and so I need to register the js again several time.
Could someone give me an hint and maybe some pieces of the core code?
Thanks in advance
Luca
Assets are published as a package. So if you want some JS/CSS to be registered somewhere and others in another situations, you should create different packages and register each of them when needed.
I am trying to generate a TEXT/XML file from a LOCAL HTML file. I know there are a lot of answers to generating a file locally, usually suggesting using ActiveX object or HTML 5.
I'm guessing there is a way to make it work on all browsers (in the end HTML extension is opened by a browser even if it is a LOCAL file) and easily since this is a LOCAL file put in by user himself.
My HTML file will be on client's local machine not accessed via HTTP.
It is basically just a form written in HTML that upon "SAVE" command should be generating an XML file in the local disk (anywhere user decides) and saving form's content in.
Any good way?
One way that I can think of is, the html form elements can be set into class variables and then using the jaxb context you can create an XML file out of it.
Useful Link: http://www.vogella.com/tutorials/JAXB/article.html
What you can do is use base64 data-urls (no support for IE9-) to download the file:
First you need to create a temporary iframe element for your file to download in:
var ifrm = document.createElement('iframe');
ifrm.style.display = 'none';
document.body.appendChild(ifrm);
Then you need to define what you want the contents of the file to download to be, and convert it to a base64 data-url:
var html = '<!DOCTYPE html><html><head><title>Foo</title></head><body>Hello World</body></html>';
htmlurl = btoa(html);
and set it as source for the iframe
ifrm.src = 'data:text/x-html;base64,'+htmlurl;