Mod developer question: How to use "$context['html_headers']" via XML

Started by Wellwisher, March 21, 2016, 07:32:30 AM

Previous topic - Next topic

Wellwisher

Hello base-gods,

1. How do I use "$context['html_headers']" in XML file? This is to create mods that require external lib files i.e jquery, font-awesome, bootstrap etc.

2. Also what is the best file to add this snippet of "html_headers" and please show a example code - as I am more of a practical learner.

nend

I don't think that is possible since that variable relates to HTML headers and not XML.

Wellwisher

Quote from: nend on March 21, 2016, 08:33:05 AM
I don't think that is possible since that variable relates to HTML headers and not XML.

I meant inside package manager install xml file.

I basically want to add files in the <head> tag using "$context['html_headers']".  Vbgamer said doing this vs doing it using "find and add" is better because it would make the mod more compatible with other themes.

Illori

you are adding that in one of the source files, so it could be in one of yours for the mod or in an existing one in SMF. it is just normal php code.

JBlaze

If you are modifying a source file (Admin.php, Subs.php, etc.), you can simply add a line like this where you are making your modification
$context['html_headers'] .= '
<link rel="stylesheet" href="http://cdn.example.com/css/style.css" />';


This will add that line to the $context['html_headers'] variable which then gets output to the template.
Jason Clemons
Former Team Member 2009 - 2012

Wellwisher

Quote from: JBlaze on March 21, 2016, 02:38:31 PM
If you are modifying a source file (Admin.php, Subs.php, etc.), you can simply add a line like this where you are making your modification
$context['html_headers'] .= '
<link rel="stylesheet" href="http://cdn.example.com/css/style.css" />';


This will add that line to the $context['html_headers'] variable which then gets output to the template.

That makes sense JBlaze, thanks for clearing that up. So which source file would be the safest to add that code to or is this a stupid question?

JBlaze

If you want it loaded on every page load, then you're best bet would be to put it in Load.php or Subs.php. Otherwise, if you only need it for specific areas, then only add it to those area's respective source files.
Jason Clemons
Former Team Member 2009 - 2012

margarett

You should also consider adding a hook which executes a custom function which would modify $context as required. No file edits is always a good thing ;) And you can hook it in, eg, integrate_load_theme
http://wiki.simplemachines.org/smf/Integration_hooks#integrate_load_theme
Se forem conduzir, não bebam. Se forem beber... CHAMEM-ME!!!! :D

QuoteOver 90% of all computer problems can be traced back to the interface between the keyboard and the chair

Wellwisher

Thank you and cheers for clearing that up @JBlaze. Much respect.  :)

@margarett That would be ideal. Being a hooker would be a dream come true here but they freak me out. I don't really understand how to 'practically' apply them. If there was a simple mod/ dummy demo with less php code as possible, I would tinker around with it. I cracked open @ahrasis existing mods that claim they're "fully hooked" to see what I can learn, but I really don't understand it.  :P

JBlaze

Jason Clemons
Former Team Member 2009 - 2012

nend

add_integration_function('integrate_pre_include','$sourcedir/file.php');

Then in the file declare your global and set the header. ;)

Antechinus

Quote from: Wellwisher on March 21, 2016, 03:59:01 PM@margarett That would be ideal. Being a hooker would be a dream come true here...

You should ask some of the local hookers about that. They may disagree. ;)


Quote...but they freak me out. I don't really understand how to 'practically' apply them.

A common problem, it seems.

margarett

Make sure you use a MOD as an example. Pick one from a developer is always a good move ;)
http://custom.simplemachines.org/mods/index.php?mod=3268

The MOD delivers a function in a Sources file called "OYTE_css()" which adds a bunch of stuff to $context['html_headers'].
function OYTE_css()
{
global $context, $settings, $modSettings;

// Add our css and js files. Dear and lovely mod authors, if you're going to use $context['html_headers'] MAKE SURE you append your data .= instead of re-declaring the var! and don't forget to add a new line and proper indentation too!
$context['html_headers'] .= '
<script type="text/javascript"><!-- // --><![CDATA[
var _ohWidth = '.(empty($modSettings['OYTE_video_width']) ? '480' : $modSettings['OYTE_video_width']).';
var _ohHeight = '.(empty($modSettings['OYTE_video_height']) ? '270' : $modSettings['OYTE_video_height']).';
// ]]></script>
<script type="text/javascript">!window.jQuery && document.write(unescape(\'%3Cscript src="//code.jquery.com/jquery-1.9.1.min.js"%3E%3C/script%3E\'))</script>
<script type="text/javascript" src="'. $settings['default_theme_url'] .'/scripts/ohyoutube.min.js"></script>
<link rel="stylesheet" type="text/css" href="'. $settings['default_theme_url'] .'/css/oharaEmbed.css" />';
}



That function all alone in the code does nothing, it needs to be hooked (LOL :P )
The package-info.xml says that a code will be executed:
<code>addHooks.php</code>
Looking into that file, there's a function called "add_integration_function". Self-explanatory, right? ;) That function receives the previous array, basically a list of "hook_name => hook_parameters". Let's look into that list, stripping what doesn't matter for now.
$hooks = array(
'integrate_pre_include' => '$sourcedir/OharaYTEmbed.php', // Kudos on requesting a file everywhere!
(...)
'integrate_load_theme' => 'OYTE_css',
);

Refer to the wiki page I linked before for details ;)
integrate_pre_include is used to point to the Sources file which you create and which contains the hook functions.
The best hook for your case is integrate_load_theme.

So the "flow" is, in short:
* SMF loads a small bunch of stuff and calls the "integrate_pre_include" hook very early in the process. That means that *all* Sources files "hooked" by all MODs now become available for the rest of the execution.
* At several points during the execution, different hooks are called. If there are functions "hooked" to that specific hook, they are executed.

So just choose the proper point in the code execution to launch your own code (meaning, choose the proper hook) and be your hooker!!!! ;D ;D ;D ;D ;D
Se forem conduzir, não bebam. Se forem beber... CHAMEM-ME!!!! :D

QuoteOver 90% of all computer problems can be traced back to the interface between the keyboard and the chair

Wellwisher

Quote from: margarett on March 21, 2016, 07:22:18 PM
So just choose the proper point in the code execution to launch your own code (meaning, choose the proper hook) and be your hooker!!!! ;D ;D ;D ;D ;D

Lol xD! Thank you @Margarett for the in-depth Hooks explaination, code snippets and mod example!
I have been reading it many times over; the more I read it, the less scarier the hooks seemed. Being a total newb, it's given me a ground to stand on so I really appreciate this, really thank you again.
It will be awesome to create very own mod hooks file and stick it in the $sources directory (like a base-god). Might try some of this out on my YT mod.  8)

I got a general question: From what I am reading (and please correct me if I wrong) this means *everything* can be "hooked", right? Then why do some developers write "partically hooked" on their modifications? Were they being lazy or are some hooks not available or are more challenging to integrate etc?  ???

live627

Allow me to quote myself:

Quote[...]There is quite the heavy lack of hooks in SMF; in fact, some mods that use hooks also use file edits. Like SimpleDesk 2.0 or Dream Portal 1.1. That is not to say file edits are inherently bad.

One thing I should note for mods that avoid file edits is that they generally do not deeply integrate with existing functionality such as deeply interacting with topics or PMs because of the blatant lack of hooks. They mainly add new sections to enhance SMF. Although, as SimpleColorizer shows, the buffer hook can be used to work wonders.

Source: http://livemods.net/index.php?action=faq

nend

Not everything can be hooked, unless you can rewrite a function, wait you can do that, but then that leaves a bigger mess in the compatibility war.

I believe the SMF devs are hard at work at putting hooks where they see needed, but no one can conceive every place a hook may be needed.

There are a few options though, maybe for SMF future.

  • Source code can be compiled after every mod install.
  • Add a strict policy and dump the package managers ability to rewrite code. Mod Devs would then resort to rewriting functions, yeah that is a bigger mess.
  • Add more hooks, places needed are inconceivable.

I actually like the compile option. Say so and so mod says I need to insert code at line 123 in file.php while another mod says I need to insert code at line 123 in file.php. Since they are compiled all at the same time the installer knows that both mods need the same line of code, less conflicts.

Then say you want to uninstall a mod, then the source code would be recompiled from scratch again, with the mods you decided to keep.

Just something I wanted to do, maybe I may try to make it, but it wouldn't be compatible with any mods at this time.  :-\

Kindred

except - by compile - you are telling us to step away from php - and even the way you describe it, it would be extremely problematic.

"both mods need to modify the same line of code"
how does "do this at compile time" differ from "change the code in php"?
Short answer.... it doesn't. you will run into conflicts with overlapping code changes -- and now... instead of partially working, you have a total failure as the compile aborts and you have no site

either that...  or everything is modular, in which case, every mod writer would need to re-write every function that they need to modify -- or they need to pass data back to the main functions via hooks...

oh, wait, that's what we're doing. :P

(yes, I used to work with PASCAL and C++, I DO know what I am talking about)
Слaва
Украинi

Please do not PM, IM or Email me with support questions.  You will get better and faster responses in the support boards.  Thank you.

"Loki is not evil, although he is certainly not a force for good. Loki is... complicated."

nend

So you know more than PHP so you must know what your talking about. Sorry I don't, with my knowledge of BASICs, VB, AS, Java, JavaScript and PHP. Maybe if I forget a few of those it would open my mind a little.

So the answer is to increase the memory footprint by adding hooks to every conceivable place. Rewriting functions that sounds like a option that isn't going to cause conflicts. Add and replace another option that isn't going to cause conflicts.

Hmm, now if those didn't have problems also.

Now let's just speculate of how compiling should work instead of throwing code at it. Just for giggles, I am going to add this to my github repo. Start work on it soon and maybe finish it within a year.

Kindred

nend,
my comment on pascal and C was not intended to be chest beating...

they are both compile-required languages...
And let me tell you... the hair pulling that resulted from having a compile of 50,000 lines of spaghetti code fail 90% through was painful in the extreme....

I can't recall if basic is -- but none of the others that you listed are languages that require a compile - they compile on the fly at "runtime".

that's my point...   distributing a compile required version of a php script is just plain silly, IMO. One of the great things about php is that it is pure script on the server side and doesn't require pre-compiling to run.

Слaва
Украинi

Please do not PM, IM or Email me with support questions.  You will get better and faster responses in the support boards.  Thank you.

"Loki is not evil, although he is certainly not a force for good. Loki is... complicated."

Deprecated

Just noting that Margaret is turning me into a hooker with the great advice I have received on how to use the integration hooks.

I'm getting so far out of control that I'm considering writing a mod that creates its own integration hook and then uses it. The concept would allow you to add a simple hook to a file you want to modify, define the hook, and then use it to your large routine, instead of adding a big chunk of code to one of SMF's normal files.

Coding is one of the art forms, but you will never master an art form until you understand the rules of that art form, and understand the occasions when it is not only proper but inspired to violate the rules. You have succeeded when your work is popularly acclaimed, even though it goes against all standards. This is true of every art form. A master violates the rules of the art form because he understands the rules, a beginner violates the rules of the art form because he doesn't understand the rules.

And spaghetti? The only place that's good is in Western movies and Italian restaurants. With the modern concepts of programming languages, particularly OO languages, it becomes increasingly difficult to write spaghetti code. ... Now if only PHP will deprecate their goto function.

Um, now you know how I got my member name! I was deprecated out of a job when my customer realized they could hire two fresh college grads for that they were paying me. Only thing they didn't understand, I know when it's the right time to violate the rules. The fresh grads on the other hand don't fully understand the rules, and violate them by accident. They manage to find out ways to churn out spaghetti in OO languages.

Advertisement: