How to pull in the path to a javascript file inside an HTML block automatically?

Permalink
I just finished setting up a tool tip functionality at my site which is working just fine.

It's not entirely my creation mind you but anyway...

The following files are involved:

tooltip.js inside the / (domain root) directory.
tooltip.css inside the /themes/my_theme/ directory
default.php inside the /themes/my_theme/ directory.

Inside the default.php file, at the top, I have this:

<link rel="stylesheet" media="screen" type="text/css" href="<?php echo $this->getThemePath().'/tooltip.css'?>" />


And of course there is the HTML code inside the HTML block thingy which reads in part...

<script type="text/javascript" language="javascript" src="/tooltip.js"></script>
<p id="zztext">Lorem ipsum dolor sit amet, <span class="hotspot" onmouseover="tooltip.show('Testing 123 <strong>Testing 123</strong>');" onmouseout="tooltip.hide();">consectetuer adipiscing</span> elit. Aliquam id tellus. Nulla orci enim, vulputate et, pharetra eget, imperdiet non, sem. Mauris sit amet mi nec nulla porttitor dapibus.


All well and good but I am wanting to limit the spread of files all over the place and put as much as I can inside my theme directory for easier maintenance.

I'd like to put the tooltip.js file inside the theme directory too but I don't want to hard code the path to that file inside the HTML block code as in..

<script type="text/javascript" language="javascript" src="/theme/my_theme/tooltip.js"></script>
<p id="zztext">Lorem ipsum dolor sit amet, <span class="hotspot" onmouseover="tooltip.show('Testing 123 <strong>Testing 123</strong>');" onmouseout="tooltip.hide();">consectetuer adipiscing</span> elit. Aliquam id tellus. Nulla orci enim, vulputate et, pharetra eget, imperdiet non, sem. Mauris sit amet mi nec nulla porttitor dapibus.


It would be nice to be able to pull in the value from $this->getThemePath() and have C5 use it inside the HTML code block but given that I can't use PHP code inside it...well...I can't.

Does anyone know how to pull in the tooltip.js file into the HTML block code using a path to where it is at without hard coding the path into there?

I'd like to pull in the CSS file there too but one thing at a time so I am focusing on the JS file first.

Carlos

PS. Oh..you can see the tooltip working at http://www.carlosgonzalezconsulting.com/test/... for anyone who is interested. Please excuse the state of the site as I am testing things and making a lot of changes.

 
carlos123 replied on at Permalink Reply
Cool!

I figured out how to pull in a CSS file from inside the code of an HTML block.

<script type="text/javascript" language="javascript" src="/themes/my_theme/tooltip.js"></script>
<link rel="stylesheet" media="screen" type="text/css" href="/themes/my_theme/tooltip.css" />


But I am having to use the full path which I am not too keen on as if the theme path ever changes I will have to go in and change a bundle of stuff that has the theme hard coded.

Carlos
jordanlev replied on at Permalink Best Answer Reply
jordanlev
Hi Carlos,
I'm not sure which tooltip library you're using, but if it's a well-written jquery one you should be able to do this without having to load any js or css into your HTML block.
(By the way, I see you have a lot of posts recently regarding putting code into the HTML block -- as a point of general architecture, I think you're barking up the wrong tree -- there is not any reason that you should need to add code to an HTML block, all code should be handled by the theme files and "real" blocks).

Anywho... here's an example of how you can do this. I'll use the tooltip library available athttp://tooltipjs.com/ for this since I don't know which one you're using. The way this works is you add a class of "tooltip" to any element you want to have a tooltip, and you add a "title" attribute containing the text of the tooltip. For example, if you have a div that you want to show the tooltip when hovered over, you would do this:
<div class="tooltip" title="This is the tooltip text, it will show up in the tooltip when this div is hovered over.">Blah blah blah</div>

Then, in the <head> of your theme templates (underneath the Loader::element('header_required') tag), add this:
<script type="text/javascript" src="<?php echo $this->getThemePath(); ?>/js/tooltipjs.js"></script>

(that is assuming you put the tooltip.js inside a "js" folder within your theme's directory)

Voila! You should now have tooltips on that element. If you want to style them, just add the appropriate CSS to the <head> of your template files as well.

One of the many reasons jquery is so awesome is because it lets you elegantly apply effects such as this to your html without having to litter the markup with code. This is referred to as "unobtrusive javascript", and it is definitely the way to go!

Best of luck,
Jordan
carlos123 replied on at Permalink Reply
Hi JordanLev.

As always your answers are thorough, easy to understand, and timely. You are an asset to this community Jordan!

A couple of comments on what you said if I might...

Why don't I use JQuery? Well...I can't stand the goobglygook that JQuery statements seem to be to me (I'd rather learn straight Javascript and do whatever Javascript allows instead of whatever JQuery allows). Also I come from a background of practice tweaking my code to make it as light and as fast as possible. As such I have never wanted to add bloat to my sites such as a Javascript library that was not really necessary (and JQuery definitely adds bloat).

However...maybe I need to rethink this as JQuery is already loaded for C5 use anyway so maybe I should get used to the Greek and chicken scratches that JQuery statements are to me and try and work with them (still there is something to be said about not adding still another language to learn on top of the other languages I try and stay on top of...information overload).

On another note...

The reason I have been posting about adding code to HTML (such as PHP and Javascript) inside an HTML block is because I have wanted to get away from putting files all over the place and to keep things together. So instead of loading things (like Javascript) in my template that will then be loaded for every single page on my site using that template (even if just a few pages out of my site actually use the Javascript) I have been wanting to attach the loading to the actual page that uses said code.

And it is working for me that way now. The only thing I haven't figured out is how to bring in the theme path without actually hard coding it in (there may not be a way around that).

So the Javascript library is loaded when needed on the very page that needs it (or the few pages that do) and nowhere else. The CSS needed for that library is likewise loaded only for the page that needs it and not added to the head of every page by being loaded through the site template.

Does that make sense?
jordanlev replied on at Permalink Reply
jordanlev
Well, everyone has their own style and preferences of course, so I won't tell you you're wrong, but I will say this:

1) There is a generally accepted idea in the industry that "programmer time is more expensive than computer time" -- meaning that for 99% of situations in today's world it is wiser to value code readability and maintainability over obsessive optimization. Sure, there are exceptions (operating systems, low-level drivers, some video games), but building content-managed websites is not one of them.

2) JQuery is in most cases *more* efficient than using raw javascript. Unless you are a complete javascript ninja, jquery's code will most likely do what you want faster than the code you write. It also smooths over many of the differences in how browsers interpret javascript, thus saving you a lot of ugly workarounds and complex if/then statements. And of course in light of point 1 above, writing a single line of code to accomplish what would otherwise take many lines of code is a huge win in terms of readability and maintainability of the code.
JQuery stands head over heels above most other libraries out there -- it is well-written, consistent, thoroughly tested (it's used by pretty much everyone these days), has excellent documentations, and if used correctly it promotes good separation of presentation and functionality.

3) I would argue that there are better ways to solve the problem of "files littered all over the place" than putting all of your code in HTML blocks. First of all, you can put all of your custom code into a package and thus keep it all inside one directory of your site. Also, you can use version control tools (like Subversion) to keep track of your code and the changes you've made to the base installation -- although this is admittedly more of an advanced technique and probably not feasible if you're a beginning programmer. Finally, if you put all of your code into HTML blocks, you lose the ability to search for things in your code, which if they were in the filesystem would be easy to do with pretty much any decent text editor (or "grep" if you want to delve into the UNIX command line).

4) If you are interested in doing things your own way and not following the conventions of the larger system (concrete5 in this case), it might really be better to *not* use concrete5 and instead build out your website from scratch. When you use any platform, you are implicitly making a deal -- you are accepting the platforms way of doing things in exchange for being able to leverage all of the features that the platform provides. To try to go "against the grain" of the platform will only lead to pain and suffering, and in the end you will have wound up spending more time working around the system than you would have if you built it from scratch.

Finally, if you're still with me after all that yammering, here is a practical solution to your problem: you could make a new page type for the pages that have tooltips and include the necessary js/css in the head of that page type only. That way, it will not be loaded on any other page.

-Jordan

PS - please don't take my comments in the wrong way (which I don't think you are) -- I genuinely appreciate your curiosity and desire to learn!
carlos123 replied on at Permalink Reply
You bring up some excellent points JordanLev. Points I will have to ponder.

Maybe I will change my mind about JQuery.

For now...I am sticking to Concrete5. It may interest you to know that I am not primarily sticking to it because I think it is the next best CMS since sliced bread.

I am using C5 for two reasons.

1. The user interface is better for my clients bar none (though they will wade into a level of complexity that is way over their heads if they do anything at all other than adding a new page and other simply things like that I think). That's a selling point that should help differentiate me from the pack of WordPress "programmers" and help me sell more website services as a consultant.

2. More importantly for my purposes I see a real need for better documentation here. A need that I hope to meet and to make some money out of by putting affiliate links in that documentation (independently hosted). The affiliate commission income giving me greater motivation to create better and more documentation than I would otherwise be motivated to create. In other words C5 represents a marketing opportunity for me not just directly in terms of building sites with C5 and being paid but indirectly in that I can rank for C5 documentation and hopefully make some affiliate commission from whatever documentation I create.

I am converting my site over to C5 to better learn it so that I can offer it to my clients and so that I can create the documentation I want to create for it.

But...I am bumping into limits or I should say conflicts between how it does things and how I would prefer to do them.

You are absolutely right in saying that I should line up with how C5 does things if I am going to use it but part of the problem of me doing so is that much of what it does is still incredibly confusing and very hard to understand.

C5's interface may be wonderful for the end user (and maybe even for developers that understand it) but compared to working with WordPress, C5's internals are incredibly complicated and hard to understand in my opinion.

Which of course presents an opportunity if I continue to work with it and come to understand what I don't at present :)

I like your last suggestion about putting everything in a package JordanLev. I'll have to play with some of the things you suggested.

Carlos

PS. Incidentally my financial needs are very, very little so at present I have way more time to devote to things like this than would be the case if, like most people, I had to work like a dog to get money for rent and all manner of other expenses in life (most of which I do not have at present). In that sense I am fortunate and can spend the time to do things myself and learn in the process (not that I want to do that all the time but it's nice to have the time to play around with things).
carlos123 replied on at Permalink Reply
Hmm...I tried adding a new page type and putting the necessary lines to bring in the javascript and CSS files that way but adding the appropriate <script> and CSS lines for doing that inside the header extra content of that page type didn't work.

Got no clue why not.

I'll keep playing with it.

Carlos
jordanlev replied on at Permalink Reply
jordanlev
Oh Carlos, there you go again trying to put all your code into the editing interface :)

What I meant was that the scripts and css calls go in the <head> of the html of your page type template file. So on your server, in your themes directory, copy the "default.php" file, and call it "tooltips.php". Now edit that tooltips.php file with a text editor. Do you see the usual html <head> stuff there (like the doctype and the Loader::element('header_required') and the <script> and css references)? If so, make the changes there. If all you see instead is the "$this->inc('elements/header.php')" line, you need to go into the elements/header.php file, copy all of the code in it, and paste it into the top of your new tooltips.php file and then make sure you delete the "$this->inc('elements/header.php')" line. Now make the changes you want.

To make sure C5 recognizes this new page type, go to Dashboard -> Pages and Themes, click the "Inspect" button next to your current theme, and the new page type should appear in the list with a checkbox next to it. Keep the box checked and click the button that says "Install" or something like that.

----

One more thing -- you should keep this rule of thumb in mind when trying to do things:

***If you're doing something through the web browser (i.e. through the C5 administrative interface -- content blocks, HTML blocks (any kind of block), or the page attributes), it will NOT run any code***

The one and only exception to this is the "php block". That's it! Other than that one exception, anytime you see a text box in your browser, know that any code you put into it will not be executed anywhere, any time, under any circumstances. Textbox == No Code. This is for security concerns -- because it is assumed developers are putting their code in code files, and only end-users are using the blocks and page attributes to fill out content, and never the two shall meet. I encourage you to join the ranks of programmers the world over and get over your fear of coding in text files. You'll have to trust me (and every programmer who has come before us) that it really is the best way to do things :)
carlos123 replied on at Permalink Reply
Thanks for your further input JordanLev.

I have no fear of coding in text files by the way. In fact I prefer it :).

Sorry I misunderstood what you were saying about adding a page type but, well...you did call it a page type not a template.

I'll try it the way you mention in this post even though I am not thrilled about having yet one more file used as a template that I have to keep aligned with the regular default.php and the view.php files with respect to the template code within them (i.e. if I change anything in the template overall I now will have to change that something in all three files to be consistent across whatever pages use any of these files).

Incidentally I know for a fact that C5 will most certainly run code, at least Javascript code inside an HTML block. I haven't tried to do so inside a content block yet but may try that sometime just for the heck of it to see if it works.

Just saying.

Thanks again Jordan.

Off to build another page template...

Carlos
barkingtuna replied on at Permalink Reply
barkingtuna
Hello, sorry to hijack the posting, but I really need help and can't seem to get a response and you seem to know exactly what you are doing. Would you mind looking at my issue and getting back to me please? http://www.concrete5.org/community/forums/customizing_c5/javascript...

Thank you
jordanlev replied on at Permalink Reply
jordanlev
Hey,
I took a quick look at that other thread, and despite your assurance that there's an easy answer, I can't think of one myself. It's usually not possible to just import a static site into a CMS. In your specific case here, you have a bunch of hardcoded images, javascript, etc. -- ideally you'd need to create a custom block to let users manage those images via the File Manager. That's a lot of work though, and not possible if you don't know PHP. There's probably a way to make it work with your hard-coded image directory too, but it depends on how the javascript works (which again is going to be really hard if you don't know javascript).
Sorry, wish I were able to help :(
barkingtuna replied on at Permalink Reply
barkingtuna
I appreciate the response, but I know enough about both to get myself into trouble. I am not importing a static site, I just rebuilt the tooltip menu using the same scripts I had previously used in the static site. All of the functionality is there except for the path to the image. I have all of the images in a folder in my Theme file and they can be called up if I link directly to them, for instance, via CSS. However, the thumbnail function resides in the javascript file that I attached and it references a direct link to the images, not a theme/path based link. I am looking for the syntax call up the images that are stored within a subdirectory in my Theme. The images are there in subdirectories in the theme, the scripts and CSS are working perfectly, there is just a path based disconnect between how the syntax of the javascript is worded as it relates to the location of the files. Does that makes sense?
jordanlev replied on at Permalink Reply
jordanlev
OOhhh.... okay that does make more sense. I will answer this on your other thread.