I have created my own little Symfony2 form type. For this to work properly, I need to include a js library. While that was a simple task when using this new form type in a single web application, it became way more difficult when I decided to move that form type to a dedicated bundle in order to make it reusable.
For now, I am aware of two possible solutions
1) Ask everyone who is using my bundle to add a line into their base.html.twig
2) Add a <script> tag for embedding the library to my form widget
Both of them are not very smart so my question is: how do I do this better? Especially, if my form type can be included several times on a single page. And even worse, if my form type is requiring e.g. JQuery to be present, but I do not know, if JQuery has already been loaded in the application.
Since you don't have any controll about where the users of your bundle actually include the JS (I know projects where they aren't included in the ::base.html.twig file, but in a file called layout.html.twig in the main bundle of the application), a good way is to provide a JavaScript file which can then be included via Assetic like the following:
{% javascripts debug=false output="js/bundles.js"
'#YourVendorAndBundleName/Resources/public/js/formtype.js'
%}
<script type="text/javascript" src="{{ asset_url }}"></script>
{% endjavascripts %}
So you basically just store everything you need in that one file located in {yourBundle}/Resources/public/js. The symfony2 command assets:install will do the rest.
This way the user could store your JS together with other vendor JS in one file and do more stuff with it like minifying etc.
Important: Make sure to add this to your installation/usage guide.
If your JS code relies on third party JS libraries like jQuery, you should not add those, as the Symfony2 Cookbook says: http://symfony.com/doc/master/cookbook/bundles/best_practices.html#vendors
Instead you could require a specific asset with a specific name, like mentioned here: Managing common javascript dependencies in Symfony 2
Related
I'm not sure if this is the best way to articulate my question.
I have a script that I want to run on one page on the site.
All of the .js files are included/imported into an app.js file which is then minified and included in the layout.html which is used on every page.
There is one javascript file I want to use only on 1 of those pages(The pages that I don't need it on creates an error in the console so I can't just leave it). What is the best way to include it. Can I still include it with the minified script but only on that page?
You basically have three options:
Include the script in the minified app.js, but modify it so it checks whether it's needed (e.g., check that the things it needs to work on are present rather than assuming they're there) before running. That way, app.js is the same on all pages, can be held in cache, your build script is straightforward, etc.
Have app.js, which doesn't include the script, and a separate minified version of the script that you only include on the desired page, using a separate script tag. Your build script is still fairly simple, and it only adds a single HTTP request to the target page.
Have two minified app.js files, app.js and app-plus.js (or whatever). Include app.js on all other pages, but include app-plus.js on the target page. This complicates layout.html because it has to determine which script to include, and complicates your build script (very slightly).
Unless the page-specific script is massive, option #1 is likely to be your best bet because of the simplicity (an extra few kilobytes once the HTTP connection is established aren't usually a big deal), but it really depends on your situation. If you need to support fairly low-bandwidth consumers (mobiles on high-rate data packages), that might argue against always including the script. It's up to you.
If you are building regular HTML + CSS + JS page, then you can just add this javascript file (or more if you want) to a separate folder and then call it in the HTML file you want.
EG - this is your structure
-index.html
-about.html
-js-for-minify/do.js
-js/not.js
-dist/minified.js
-css
you can reference the about.html to have a script tag which is directed of the unminified file.
<script src="js/not.js">
while for the index.html you can reference the minified file
<script src ="dist/minified.js">
I checked PyCharm knowledge base and "Google" but could not find if there is an equivalent to django template comments for "standalone" JavaScript files.
In Django, the following is not rendered when producing html pages (which also works for JavaScript code if it is in the template file):
{# this won't be rendered #}
// this will be rendered
source: https://docs.djangoproject.com/en/dev/topics/templates/#comments
Because I would like to separate JavaScript code from the template (put it in mySeparetedJsCode.js and including it via a script tag), the django template {# comment #} does not work anymore.
does someone know a solution for this?
What you want is a javascript minifier that will drop comments for you and do other space-saving measures, Uglify is a popular one that you can manually run on your js files when you deploy your code or anytime before that.
How to configure your minifier is application specific but with uglify it's controlled by the preserveComments directive, set preservComments: "some" which will keep any comment that starts with a ! and the rest will be removed, set it to "all" and all comments will be removed.
The common solution is to have a javascript toolchain setup for this as you always want to serve minified files in production. djangos collect-static is a good place to have any automated process if you dont have a build system in place.
For example django-webpack-loader, django-pipeline and django-compressor are packages that already does this for you.
I am building an app in JQM that has multiple instances but the same core of scripts.
Summarizing, every instance will have its own index.html initializing that particular instance with files both taken from the central repository (the common scripts/interface) and from the particular instance (files specific to that instance only).
Since I am adding more capabilities to the application, I need to constantly update the core of scripts with new addons (both 3rd party or custom scripts), but I don't want to go and update all the single instances with the new scripts I'm adding.
My question is: is there a method to include a <script> tag inside the index.html of every instance (say <script src="commonurl/commonscripts.js"></script>) and on my common repository, in the commonscript.js use structures like the java import, to import all the scripts I'm using?
I know it's not how js works, but the core of the question is: do you have any suggestion on how to keep the client unvaried and work just on the server side modifying just the included file, or anyway not having to manually modify the client index.html? Is js minification/merging my only option?
Same question applies to CSS files included in the client index.html.
Hope this makes sense, thanks for the answers!
You can do this with requirejs
RequireJS is a JavaScript file and module loader. It is optimized for
in-browser use, but it can be used in other JavaScript environments,
like Rhino and Node. Using a modular script loader like RequireJS will
improve the speed and quality of your code.
http://requirejs.org/docs/start.html
I use some Facebook JS scripts for user authentification, etc. I want to place them in the properly unobtrusive way as application-wide scripts.
Currently I have the script as a partial and call it from my application header:
<%# render 'layouts/facebook_app_scripts' %>
The script works but is extremely obtrusive. I want to make it unobtrusive. This is especially important since I tap into all sorts of APIs and it's getting messy.
You don't need to see it in its entirety (if you need to see the script to answer this question, I don't think you'll be any help as this is a general question not script-specific)
You should know that it contains dynamically created links such as this one:
window.top.location = "<%= Facebook::SITE_URL.to_s %>/logout";
That means that putting this in a .js file in the assets/javascript folder isn't going to work, since .js files can't access rails-generated variables.
So how can I shift my javascript with dynamically-generated links from the rails view to an unobtrusive javascript file?
Take a look on this project to include all the Facebook JS SDK as a gem
Is there a way to link multiple javascript files without making them one file?
What I would like is to have one file (javascript or otherwise) which houses links to my other javascript files.
For example, the webpage has one file called allmyscirpts.js, and inside this file is a list of links to my actual individual, separataed javascript files.
Is this possible?
Tod
JS can't simply import more JS, but you could easily write a simple server-side script that concatenates your files together. If you can't/won't work on the server, scriptloader libraries are very plentiful out there these days. Check out require.js, lab.js, yepnope.js, etc. and see if one of them suits you well.
The only way I can think of is to load Javascript files through ajax. The YUI Loader you to not only load all your js files (and those from YUI) within javascript, but it also allows you to configure dependencies between your js files. So For instance, if widget1.js requires global.js, you can configure that dependency, then you can tell the loader to load "widget1" and the loader will also load global.js when it loads widget.js.
Unlike css, I do not believe there is built in syntax in javascript that automatically includes another javascript file. But there are javascript utilities out there that allow this.
For a simpler solution than the YUI Loader, check out the YUI get utility. For my projects I have setup the YUI loader, and as a result my HTML pages only have about 2 or 3 javascript files included, and the rest of what I need is loaded on demand by the Javacript controller for that page.