! Summary - What Does It Do?
The Plugin Library allows __Selected__ Library Functions to be accessed. The most important is shown in {LIB func='libAddAnchorLink' anchor='libAddAnchor' txt='__Example 1__' } {/LIB} which deals with Anchors and Links to them. At this point - all of the remaining Examples demonstrated different kinds of Boxes.
! Why Not Just Create Plugins?
The answer is time! Each and every Plugin requires a significant amount of time spent in it's creation / writing and rewriting the help / debugging / etc. A Library Function and this Plugin provide an alternative. Adding __Simple__ functionality can be accomplished very quickly in a Library Function. Providing Users with access to it (this Plugin) can also be accomplished very quickly.
A large percentage of our existing Plugins could be replaced with Library Functions. I'm only stating a fact - __Not__ making a suggestion __or volunteering__. Plugins are still needed - but the complexity required should be the governing key.
Another issue is - at this time - the functionality provided by Library Functions can not be controlled (turned off) like a Plugins can be.
! How Does It Work?
This Plugin functions like every other Plugin even though the Library Functions define most of the Parameters. In this example only the Parameter __func__ is defined by the Plugin.
^~np~{LIB func='libHeaderBox' header='My Header' }Life is Grand!{/LIB}~/np~^ {LIB func='libHeaderBox' header='My Header' }Life is Grand!{/LIB} The specifics of each function is defined in the next heading: __The Plugin's Help__.
!- The Plugin's Help
{PLUGINHELP plugin='LIB' }
! Between The Code Blocks? {LIB func='libAddAnchor' anchor='Between The Code Blocks' } {/LIB}
For those of you who don't know - the term Code Block refers to the way a Plugin is called. Some Plugins only require a single Code Block to operate while others need two. Examples are:
* __~123~))AGENTINFO(( info= ~125~__ requires a Single Code Block while
* __~123~CODE source= num= ~125~Source Code~123~/CODE~125~__ requires Two Code Blocks. The first is __~123~CODE source= num= ~125~__ and the second is the closing __~123~/CODE~125~__.
Most Plugins that require 2 Code Blocks do so because they expect a lot of data and are designed to work on it. They use Parameters to control what they do to the data between the Code Blocks. The Plugin Library does this as well. That allows all of the boxes to contain as much data as you want to place into them.
! Examples
!!- Example 1 - ))libAddAnchor(( & ))libAddAnchorLink(({LIB func='libAddAnchor' anchor='libAddAnchor' } {/LIB} {LIB func='libAddAnchor' anchor='libAddAnchorLink' } {/LIB}
These functions work together to add Anchors and Links to them. For those of you who don't know - an Anchor is a marker that allows you to jump to it. The best example of this are the Links located in the Table of Contents which are created with __~123~maketoc~125~__. Unlike the Anchors created for the Table of Contents (which use a Visible Header to define them) - Anchors created by __))libAddAnchor((__ do not need to be visible and are not normally displayed in the Table of Contents.
As an example, the Top and Bottom of this page (and all of the Examples) have Anchors created with __))libAddAnchor((__. This is what the calls look like:
^~np~{LIB func='libAddAnchor' anchor='PageTop' } {/LIB}~/np~^ ^~np~{LIB func='libAddAnchor' anchor='PageBottom' } {/LIB}~/np~^
Adding a Link to an Anchor is accomplished with __))libAddAnchorLink((__ like this (be sure you use the same Anchor Name with both functions):
^~np~{LIB func='libAddAnchorLink' anchor='PageTop' txt='Top of Page' } {/LIB}~/np~^ ^~np~{LIB func='libAddAnchorLink' anchor='PageBottom' txt='Bottom of Page' } {/LIB}~/np~^ ::-->{LIB func='libAddAnchorLink' anchor='PageTop' txt='Top of Page' } {/LIB}<-- -->{LIB func='libAddAnchorLink' anchor='PageBottom' txt='Bottom of Page' } {/LIB}<--::
That does not mean that the Anchors created by __))libAddAnchor((__ have to be invisible or that they can not be displayed in the Table of Contents. At times a visible Anchor can come in handy - even if they don't __Do__ anything. This creates a Visible Anchor:
^~np~{LIB func='libAddAnchor' anchor='Example1A' txt='Anchor Example1A' } {/LIB}~/np~^ ::-->{LIB func='libAddAnchor' anchor='Example1A' txt='Anchor Example1A' } {/LIB}<--::
The following Header was created with this:
^~123~LIB func='libAddAnchor' anchor='A ))libAddAnchor(( Header' level='3' } ~123~/LIB}^ {LIB func='libAddAnchor' anchor='A ))libAddAnchor(( Header' level='3' } {/LIB} This Anchor looks like a normal Header and it is included in the Table of Contents.
!!- Example 2 - ))libBox(( {LIB func='libAddAnchor' anchor='libBox' } {/LIB}
A __))libBox((__ is just a simple Div Box that looks a lot better (in most of the Templates) than the Boxes created with Carets like the one below.
^~np~{LIB func='libBox' }Mary Had A Little Lamb{/LIB}~/np~^ {LIB func='libBox' }Mary Had A Little Lamb{/LIB} That produced a nice Box with a message in it. Nice but not a big thing - Right?
!!- Example 3 - ))libErrorBox(( {LIB func='libAddAnchor' anchor='libErrorBox' } {/LIB}
The __))libErrorBox((__ creates a nicely formatted Box with a Header and Body sections.
^~np~{LIB func='libErrorBox' header='This is the Header' }And this is the Message{/LIB}~/np~^ {LIB func='libErrorBox' header='This is the Header' }And this is the Message{/LIB} Again - this is nice but not a big thing - Right?
!!- Example 4 - ))libHeaderBox(( {LIB func='libAddAnchor' anchor='libHeaderBox' } {/LIB}
Like the __))libErrorBox((__ - all that the __))libHeaderBox((__ does is create a formatted Box with a Header and Body sections.
^~np~{LIB func='libHeaderBox' header='This is the Header' }And this is the Message{/LIB}~/np~^ {LIB func='libHeaderBox' header='This is the Header' }And this is the Message{/LIB} If you're still looking for that big thing - I hope you find it!
!!- Example 5 - ))libContractedHeaderBox(( {LIB func='libAddAnchor' anchor='libContractedHeaderBox' } {/LIB}
This Box is almost identical to the function __))libHeaderBox((__. The only difference is that a Plus/Minus Icon is located in the Header which Expands/Contracts the Message Section of the Box.
^~np~{LIB func='libContractedHeaderBox' header='This is the Header' }And this is the Message{/LIB}~/np~^ {LIB func='libContractedHeaderBox' header='This is the Header' }And this is the Message{/LIB} I hope this a little closer to what your looking for? Hay - I'm trying!
!!- Example 6 - ))libTabBox(( {LIB func='libAddAnchor' anchor='libTabBox' } {/LIB}
I like Tab Boxes. I don't really know why - but I do - so I had to add this function. All that it does is create a Tab Box for your viewing pleasure.
^~np~{LIB func='libTabBox' title='My Tab' }And this is the Message{/LIB}~/np~^ {LIB func='libTabBox' title='My Tab' }And this is the Message{/LIB}
!!- Example 7 - ))libContractedTabBox(( {LIB func='libAddAnchor' anchor='libContractedTabBox' } {/LIB}
Did I mention that I like Tab Boxes? This is the same Tab Box created with the function __))libTabBox((__ except the Message area can be Expanded/Contracted.
^~np~{LIB func='libContractedTabBox' title='My Tab' }And this is the Message{/LIB}~/np~^ {LIB func='libContractedTabBox' title='My Tab' }And this is the Message{/LIB} If you haven't found that big thing yet - you never will! It just doesn't get any better than this.
!- Errors
This Plugin does a lot or error checking and produces a lot of very similar Error Messages - depending on what was done wrong. Here are a couple of examples:
^~np~{LIB func='libBadFunctionName' } {/LIB}~/np~^ {LIB func='libBadFunctionName' } {/LIB} Obviously - you can't expect a function that doesn't exist to do anything except give you an Error Message.
! Final Thoughts
This page demonstrates how simple functions can be added to provide a User with __Options!__ These functions are fairly simple and didn't take a long time to create. Almost nothing in comparison to a Plugin - so as time passes - I think there will be a lot more of them.
In any case - Enjoy
[http://www.bitweaver.org/users/index.php?home=StarRider|StarRider (s-r on IRC)]
{LIB func='libAddAnchor' anchor='PageBottom' } {/LIB}


{LIB func='libAddAnchor' anchor='PageTop' } {/LIB} {COMMENT }
1- Please use this format when adding new examples
2- Every Library Function needs an Example xxx - FunctionName Anchor combination as shown. I will admit that adding an Anchor to a Heading looks strange but on this page it is unavoidable. That is because the Help for { LIB } provides a link to this page with an Anchor - so the Anchor need to be findable - which is not the case when they are inside a Contracted Header.
!!- Example x - ))libFunctionName(( {LIB func='libAddAnchor' anchor='libFunctionName' } {/LIB}
Explain what the Example should do
^~np~{LIB func='' p1= p2= p3= } {/LIB}~/np~^ {LIB func='' p1= p2= p3= } {/LIB}
Explain what is special about it
{COMMENT}
! Introduction
{maketoc}The Plugin Library contains a lot of small, self-contained functions that are designed to do specific tasks. Some of them are useful to a User. This Plugin provides a Gateway to those functions.
!- History
This Plugin came about almost by accident. While working on another Plugin I had a function naming conflict and realized that any function defined in a Plugin is global in nature. Since a large percentage of the code in a Plugin is repetitious - a library of functions could reduce a lot of repetitious code. Further - it could eliminate a lot of time in the development of a new Plugin while increasing their functionality.
A Library was created and I started converting the Plugin I was working on to use it. A little later - I realized that some of those functions could be useful to a User.
I decided to create the Plugin to make that happen but the main question was - where was the extra information needed going to come from. There were several options but I wanted maintain the same methodology used everywhere else in bitweaver. By that I mean that nothing could be hardwired. Additions or modifications to the Library had to be automatically included. With Plugins this is done with a registration process that works quite well - but I didn't want all of the overhead that this would require.
There was also a Page Space problem that had to be addressed. We have a __Lot__ of Plugins and their Help and Parameter Data take a __Lot__ of space. This Plugin would only make matters worse because each Function would need a Description and it’s own set of Parameter Data. I had a discussion about this on IRC with [http://www.bitweaver.org/users/index.php?home=Xing|Xing] a couple of months before but I think he was too busy to fully understand what I was talking about. In any case - I wanted to make some improvements of my own.
__The Communication Problem__ didn't prove too be as difficult as I thought it would be - but in solving it I found another problem: __Error Testing__. In a Plugin - every Parameter a User enters has to be validated for existence and then converted to the proper type for usage. That isn't a big thing in a Plugin - but doing it in each and every Library Function would have defeated the reason for creating the Library in the first place. Obviously - this Plugin would have to do the Error Testing for every Library Function - which provided the excuse I needed to create several more generic Library Functions.
I knew how to make the Load Function work - but it was the Help Function that proved to be the most troublesome. I created an Array in the Library that contained all of the necessary information (and it just kept growing). The Library was Global - Right? Not to Arrays! I don't know how many days I spent trying to find a way to access that Array (and I probably wouldn't admit it if I did) - but every approach I found simply didn't work. Upset? __That's putting it mildly!__ I felt like a bloody failure so - __I tried to Cheat!__
My Load Function basically builds a Library Function call in a string and then executes it. So why couldn't I do that with the Array? What I needed was a way to convert a ))Multi-Dimensional(( Associative Array to a String that could be then be used to recreate the array. It took a lot of time but I got exactly what I wanted - it works beautifully - but there was a problem. Stupid quotation marks! Adding a single quotation mark like this - It's about time - would cause it to crash big time. The worst part was that it always gave the same error message - not very helpful. Scratch that idea! Eventually - I expanded the ))LibertySystem(( a little and added a couple more methods.
In the process of getting the kinks out of the Help Function (it is very different from the average Plugin) - I solved the Page Space problem by changing the way the Plugin's Help is displayed. Of course that meant modifying the Plugin __((DataPluginPluginHelp|PluginHelp))__ to make it look the same. I don't mind saying that I think they are pretty slick now.
I thought I was finally finished and was writing this page when I realized something that stopped me cold. Most of the Library Functions accessed by this Plugin are Boxes and the Plugin was using __))requires_pair((__ set to __False!__ That meant that all of the data sent to those boxes had to be placed in parameters. For a Box that would be very limiting. Sounds like a minor inconvenience - Right? __Ha!__ - I thought so at first. I saw an easy solution and made it work - but the more I thought about it - the less I liked it. It required the user to specify where the data was coming from. Clunky! I knew I was going to make the changes to do it right - even if that meant changing everything. It wasn’t quite that bad - but it forced me to rewrite my load function from scratch.
Page History
Date/CommentUserIPVersion
04 Aug 2006 (16:57 UTC)
ieeee, can't even begin to figure out what is going on here.
mlpvolt206.248.132.1092
Current • Source
Lee LaMont Bell Jr.24.117.169.2411
View • Compare • Difference • Source