Categories > TinyButStrong general >

3.7

The forum is closed. Please use Stack Overflow for submitting new questions. Use tags: tinybutstrong , opentbs
By: ege
Date: 2011-03-19
Time: 03:00

3.7

Congratulations Skrol. Your continuous work on TBS over the years is worth praises and respect. I think your effort on modernising the back-end and keeping up with recent infrastructure introduced in php is of an excellent quality. I've been taking advantage of ArrayAccess support since quite sometime. And knowing that TBS is still there and evolving is very conforming. I can keep using it!

I wonder when I will find time to fork your work so that "null" variables will work as if they are empty string, without ;noerr. Something like $tbs->NullVars=true? And maybe change the signature of callback functions of ondata and onformat to get rid of the first $var parameter (which I never used, not even once in 4 years), and use return value instead of modifying the "$val" parameter so that they are callable from php without modifications (and calling php built in one liners like strtolower)? Or being able to call ondata for a simple object variable, instead of an array of objects, so that those functions are reusable even with MergeField? And those nasty simgle quotes not being converted by htmlconv=true ;)

Ah, I hope your decision to drop support for php4 will give you some more time to enjoy life. :)

Thanks again and best regards.

ege
By: Skrol29
Date: 2011-03-20
Time: 21:50

Re: 3.7

Hi Ege,

Thanks for your feedback :-)

> I wonder when I will find time to fork your work so that "null" variables will work as if they are empty string, without ;noerr

The problem is that PHP gives no way to know when a variable is set even if it's NULL.
For global variables we can use
array_key_exists(varname,$GLOBALS)
because this function does the difference.

> And maybe change the signature of callback functions of ondata and onformat to get rid of the first $var parameter

I quite agree if you mean the argument for the block's name.

> use return value instead of modifying the "$val" parameter so that they are callable from php without modifications

I agree, but it's to be studied because the argument given by reference may be quite faster than a value returned by the function.

> Or being able to call ondata for a simple object variable, instead of an array of objects, so that those functions are reusable even with MergeField?

I don't understand what you mean.


By: ege
Date: 2011-03-20
Time: 23:59

Re: 3.7

Hello,

About null variables, I know about the problem. I actually meant something like [anobject.noSetVar] syntax give errors if used without ;noerr. But php's natural behavior is to put an empty string instead of giving an error. So I end up bunch of noerr everywhere in my templates or I have to declare those variables in php, a redundant action. Simpy put, I find myself constantly putting noerr when I want tbs to print empty string which php would naturally do unless you set php's error reporting to a draconian value. I want TBS to treat unset or null variables so that it simly prints '' by default, without the need of noerr.

Yes, about the callback functions for ondata, onformat I meant the blockname parameter. I didn't find any use of it but existence of it reduces the re-usability of those functions. I frequently need to call them both from templates and php. When calling from php I have to call them with an extra parameter like callbackfunc(null, $value). Removing the blockname parameter would also render some of the php's internal functions usable by tbs templates out of the box, something like this: [anObject.aField;onformat=strtolower]. Of course it requires my other suggestion as well: return value should be returned as function's return, not by modifying the parameter.

On the speed of callback functions, I don't think returning the values by return $val;,  should make a significant overhead. It is, after all, the default and most natural way of returning values from functions.

>> Or being able to call ondata for a simple object variable, instead of an array of objects, so that those functions are reusable even with MergeField?
>I don't understand what you mean.

This is another thing I experience in almost every project I do with TBS. Imaginge a blog application. In one page, we have list of blog posts to show some summary of them:

$tbs->MergeBlock('blogPosts',$blogPosts); //where $blogPosts is an array of blogPost items.
<a href='[blogPosts._slug]'>[blogPosts.title;ondata=preparePost;block=li]</a>
(where _slug is a property set by the function preparePosts, not an original property of a blogPost item)

All is very nice but when you want to use the same functionality on the post''s detail page (permalink page where you see the entire post in detail), you have only:
$tbs->MergeField('blogPost',$blogPost); //where $blogPost is only one item, so we can't use ondata, as there is no block defined.

What I currently do to circumvent is this:
$tbs->MergeBlock('blogPosts',array($blogPost));

What I want to do is:
$tbs->MergeField('blogPost',$blogPost);
<a href='[blogPost._slug]'>[blogPost.title;ondata=preparePost]</a>

All of the suggestions I made is to improve the natural flow of programming.

I hope I made sense.

Best regards,
ege.
By: Skrol29
Date: 2011-03-22
Time: 21:41

Re: 3.7

> I find myself constantly putting noerr when I want tbs to print empty string

Most of PHP functions return value false in order to mean "no result". The value NULL has not bee choosen probably because of its strange behavior to be a value that can also "destroy" a variable. So what don't you prefer to change the value that mean 'no result" ?

> What I want to do is:
> $tbs->MergeField('blogPost',$blogPost);
> <a href='[blogPost._slug]'>[blogPost.title;ondata=preparePost]</a>

In my opinion, the MergeBlock process is quite different from the MergeField process.
MergeField is merging fields on by one, and each field is not supposed to know they are other fields, the precess can stop at any time. Typically: merging PHP variables uses a MergeField process.
But what you're trying to have is a bing overs values during a MergeField (that's your "ondata=preparePost"). This is the logic of a MergeBlock.

By: ege
Date: 2011-03-22
Time: 22:43

Re: 3.7

>Most of PHP functions return value false in order to mean "no result". The value NULL has not bee choosen probably because of its strange behavior to be a value that can also >"destroy" a variable. So what don't you prefer to change the value that mean 'no result" ?

Hmm, maybe I couldn't express myself correctly, so let the code speak :)

<?php
if ($_GET['formPosted']=='1')
   $result='Thank you for sharing.";

if we would use php instead of tbs we would write:
echo $result;

That's it. On most php error settings the code will produce an empty string, exactly what we want: We want to display "thank you" message only if user submitted the form.

On TBS:
[onshow.result]

Tbs will throw an error if the form is not posted, contrary to php's default behavior on normal error settings. This is such a common coding practice in php that I can hardly see any reason why it's not possible in TBS. If people want to declare variables before they use it, fine, current setting just allows that. In some strict error settings where variables should be declared first in order to prevent errors, this will already be caught by php. So, in my opinion, it's redundant TBS is taking such responsibility, it should completely be left to the php side, tbs should behave just like how php behaves, as expected. But people who don't chose it have currently no option but to suppress errors where there is actually no error.

Following sample is from a site I'm currently coding and it is a very tiny piece of the whole project:
            <div id="aProjectTopInfo">

              <div id="aProjectContentFotoHolder">
                <img src="[project._image;noerr;magnet=img/]" alt="[project.title]" title="[project.title]" />
              </div>

              <div id="aProjectArticleInfo">
                <ul>
                  <li>Location: [project.country.name], [project.country.continent]</li>
                  <li>Category: [project.category.name]</li>
                  <li>Published: [project.approvedDateTime;onformat=formatDate]</li>
                </ul>

                <div class="greenLike">[onshow;block=div;when [project.approved]='yes']
                  <a class="socialMediaLink greenLikeTrigger" href="/greenlike/project/[project.id]/" title="GreenLike">GreenLike
                     <span class="greenLikeCount">[project.greenlike]</span>
                  </a>
               </div>

                <div class="bookmark">[onshow;block=div;when [var._SESSION.member.id;noerr]+-0]
                  <a class="socialMediaLink bookmarkProject" rev="Project" rel="[project.id]" href="#"
                           title="Bookmark this project so you can reach it from your profile page.">Bookmark</a>
               </div>
              </div>

              <div id="aProjectArticleLogo">
                <img src="/[project.companyLogo;noerr;magnet=img/]" alt="Company Logo" title="[project.companyName;noerr]" />
                <a class="allCompanyProjectsLink" href="/projects/company/[project.companyName;noerr;magnet=a;htmlconv=url]/">
                     All [project.companyName;noerr;magnet=a] Projects &gt;&gt;
                </a>
              </div>
            </div>

Now see companyLogo, companyName, _image and especially $_SESSION can be null. They are sometimes simply not set. In 10-20 lines of html I had to use ;noerr 6 times. Just to achieve the default php behavior.

If I was to change the value so that it means "no result", that is "false" as you suggested, I would have to set all the variables on the php side. I would as well declare them like $project->_image=''; so that they have default non-null value, but this would defy the whole purpose, that would mean I was helping TBS instead of it assisting me. By putting noerr everywhere I feel like I'm doing a constant hack to a very common thing that would be naturally done.

I don't know, maybe I'm doing something completely wrong.
By: lauren
Date: 2011-04-01
Time: 00:52

Re: 3.7

forgive me jumping into this discussion but i had to just say that:

<?php
if ($_GET['formPosted']=='1')
   $result='Thank you for sharing.";

strikes me as very bad programming practice ... you have a codepath that will try to use a non-existant variable and you want it not to produce an error or even a warning? this is absolutely illegal in most languages i have ever used and for good reason, so i would like to say that the error output from TBS in this case is a good thing imho
By: ege
Date: 2011-04-04
Time: 16:27

Re: 3.7

>>...you have a codepath that will try to use a non-existant variable and you want it not to produce an error or even a warning? this is absolutely illegal in most languages i have ever used and for good reason...

True, most languages don't allow the use of undeclared variables. I also agree that it's not the most disciplined programmer's choice either.  On the other hand, every language has its own peculiarities and php is different in the sense that although you can configure it to produce warnings in such cases, the default, out-of-the-box configuration doesn't produce any warnings. So, yes, I expect no error/warning to be produced and it is the already the default behavior.

edit: PHP configured to show warnings on undeclared variables even forces you to check array indexes. So above code, properly written, would look like this:
$result='';
if (isset($_GET['formPosted']) && $_GET['formPosted']=='1')
  $result='Thank you for sharing';
This is about 60% more coding for the same effect, which doesn't even make the code more cleaner or easier to read either. Just my opinion.
By: Skrol29
Date: 2011-04-05
Time: 21:11

Re: 3.7

> if (isset($_GET['formPosted']) && $_GET['formPosted']=='1') $result='Thank you for sharing';
> This is about 60% more coding for the same effect, which doesn't even
> make the code more cleaner or easier to read either.

This is what you have to do in order to have portable code.

> If I was to change the value so that it means "no result", that is "false" as you suggested,
> I would have to set all the variables on the php side.

This is what I quite always do. I variable which is not set often mean for me a forgotten variable.