Override functions without bootstrap
I want to override functions from /library/core/class.format.php
and /library/core/functions.general.php
and found several discussions concerning that. It works with /conf/bootstrap.after.php
but I do not like that.
First one tells me not use bootstrap, but to do that with a plugin. I'd prefer that because I want to offer a plugin solution not a copy and paste instruction: http://vanillaforums.org/discussion/22107/can-any-function-be-overridden-via-bootstrap
What I have right now uses a "Gdn::FactoryInstall". How would I use that in my plugin? I've tested it in my Setup function but that didn't work...
Best Answers
-
businessdad MVP
@R_J said:
I want it to replace the core formatter!In such case, what you are doing is correct. You are passing your class to Vanilla's factory, telling it "when someone asks for a
MentionsFormatter
, use my class". I would just recommend to move the new class to a separate file, to be tidier.5 -
Linc Admin
For GetMentions, simply defining it in your plugin will override it, because it's a function (not a method). All our functions are wrapped in a is_defined condition to make them overridable.
You can't override the Gdn_Format class or its methods because it doesn't extend Gdn_Pluggable (like the Gdn_Form class, for example). If it did, you could use the _Create convention to override.
If you're simply trying to change the pattern matching in Gdn_Format::Mention, I'd support making that a config variable so that it can match the username validation which does that.
6
Answers
One of my plugins overrides classes such as the
ActivityModel
by simply declaring them, with the same file and class name. I'm not 100% sure it will work with every class, but you can try:class.format.php
and put it into the plugin's folder.My shop | About Me
Nope, it does not I just tested it on class.format.php, don't know if it might work on functions.general.php.
Here's what I've got working in bootstrap.after.php:
I have now hooked
Base_Render_Before
to execute "Gdn::FactoryInstall('MentionsFormatter', 'UmlautMentionsFormatter', NULL, Gdn::FactoryInstance);" each time and included the above code (without the last line) in setup.That seems to work, but I'm unsure if it is "right" from a developers point of view.
Based on the example, I fail to see the purpose of using the factory installer. The
UmlautMentionsFormatter
is just a simple class and it doesn't have anything to do with the core formatter. You can simply load the class in the code, as needed:My shop | About Me
Sorry, I should have explained what I try to achieve before asking how to...
I want to replace the GetMentions from functions.general.php and Mentions from class.format.php
If doing it the way above (which btw I have stolen from that discussion that I do not really understand http://vanillaforums.org/discussion/18144/最新版本中文用户名解决方案) it works.
I want it to replace the core formatter!
In such case, what you are doing is correct. You are passing your class to Vanilla's factory, telling it "when someone asks for a
MentionsFormatter
, use my class". I would just recommend to move the new class to a separate file, to be tidier.My shop | About Me
For GetMentions, simply defining it in your plugin will override it, because it's a function (not a method). All our functions are wrapped in a is_defined condition to make them overridable.
You can't override the Gdn_Format class or its methods because it doesn't extend Gdn_Pluggable (like the Gdn_Form class, for example). If it did, you could use the _Create convention to override.
If you're simply trying to change the pattern matching in Gdn_Format::Mention, I'd support making that a config variable so that it can match the username validation which does that.
@Lincoln: I'm toying around with something like
@"test user"
or@<test user>
and hope to find an answer to the ever ongoing discussion concerning Vanillas mention featureRight now I'm here but it is not working
C('Plugins.MentionsPlus.MentionStart') is
ß?
right now. I just see where it get's me...By the way: I'm using this nice site to test my regexes https://www.debuggex.com
HA! Well, I haven't tried GetMentions yet, but the mentionsformatter works like a charme
Does anybody mind trying mentions+?
https://github.com/R-J/MentionsPlus
I think I'll make it an official addon when I've proven the mentioning function itself is working...
We've done a plugin that modifies mentions to allow spaces by using double quotes, much like your example above. If you get stuck on how to do it without hacking core, let me know and I'll look up how it was done. I can't open source it because it was client-specific (and not how we want to implement it in core or support at all) but I don't mind pointing the way.
That's truely great to hear! In fact I have a problem that I can not solve. When I look at Gardens function Mentions
and GetMentions
it looks to me as if I would only need a class of my own with functions FormatMentions and GetMentions.
The way I've done it (calling
Gdn::FactoryInstall('MentionsFormatter', 'UmlautMentionsFormatter', NULL, Gdn::FactoryInstance);
in Base_Render_Before`works perfectly for FormatMentions, but it does not work for GetMentions...Obviously Base_Render_Before isn't the right place to hook but where would my FactoryInstall be placed best?
I'm quite happy with the FormatMentions part right now. I'll try to do the work with just one preg call but that's just cosmetic.
I've even seen in a Zombie thread that someone asked for a translation for
/me
. If I get it right, it will be a snap with this plugin, too.So all I need now is that my own GetMentions function is called...
I believe you want to put the factory install line in your plugin's
__construct()
method.Search first
Check out the Documentation! We are always looking for new content and pull requests.
Click on insightful, awesome, and funny reactions to thank community volunteers for their valuable posts.
Factory, construct... I'm beginning to feel like the passenger that has to land the Boing after the pilot had a heartattack
It might be about time to learn the basics...
All right, will try it out and give feedback!
Boing crashed
@hgtonight: Nope, putting the factory call magic into __construct doesn't work either.
By now the only thing working was putting it into /conf/bootstrap.after.php which I wanted to avoid in order to make it possible to put everything into one plugin.
I think I'll make a pre-release with the drawback that user have to alter/create bootstrap file manually so that I've got a chance for peregrines vote for plugin of the year
I've tried Base_Render_Before and and __construct until now, using Vanilla 2.0.18.8. I will try the __construct way with 2.1b2 later...
Also not working with 2.1b2, but plugin is released nevertheless! http://vanillaforums.org/addon/mentionsplus-plugin
You just need to define GetMentions in your plugin file, outside the class so it is a function, not a method.
My plugin now looks like this:
and I get following error message:
Fatal error: Cannot redeclare GetMentions() (previously declared in /vanilla_2_0_18_8/library/core/functions.general.php:1105)
~~~
Balls. I guess functions.general is getting called too soon. What a pain.
Don't mind. It works with
bootstrap.after.php
and I made an epic README on how to use it that way. But thanks for your efforts!I simply don't like the idea that it is not possible to use the comfort of the standard Vanilla plugins where enabling and disabling does all the work. In order to make my plugin fool proof, I would now also have to make a popup note on plugin disable to remember the user to manually clean up bootstrap, I guess and that is the dirty work I don't like to do...
Perhaps I just write that step in the README, too and don't code anything at all concerning OnDisable
now, we all we need is the casual users who haven't voted to vote
http://vanillaforums.org/discussion/25578/nominations-for-best-plugin-created-this-year
I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.