Smarty Forum Index Smarty
WARNING: All discussion is moving to https://reddit.com/r/smarty, please go there! This forum will be closing soon.

How come i can't do this? (Answered but now need suggestion)

 
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Smarty Forum Index -> General
View previous topic :: View next topic  
Author Message
okidoki_howie
Smarty Rookie


Joined: 16 May 2003
Posts: 8

PostPosted: Fri May 16, 2003 12:54 am    Post subject: How come i can't do this? (Answered but now need suggestion) Reply with quote

{section name=item loop=$items}
{$items[item].$smarty.const.ITEM_NAME}
{/section}

When i replace "$smarty.const.ITEM_NAME" with the actual value, then it works.

I might have missed the answer to this question in the docs. Sorry if i did.


Last edited by okidoki_howie on Fri May 16, 2003 7:16 am; edited 1 time in total
Back to top
View user's profile Send private message
boots
Administrator


Joined: 16 Apr 2003
Posts: 5611
Location: Toronto, Canada

PostPosted: Fri May 16, 2003 2:13 am    Post subject: Reply with quote

Yes, this peculiar behaviour is discussed occassionally because it has a more general cause.

AFAIK, the problem is that Smarty can't parse something like
    $items[item].$smarty.const.ITEM_NAME

because the dynamic var in the dot notation is itself using dot notation.

Is it supposed to be read as
    $items[item].$smarty.const.ITEM_NAME
or
    $items[item].$smarty.const.ITEM_NAME
or
    $items[item].$smarty.const.ITEM_NAME ?


Smarty doesn't know otherwise, so it assumes the last case (ie. it replaces $smarty in the dot notation which evaluates to Array here which blows it up in this case). I think it should know for built-ins, but it doesn't. Unfortunately, the otherwise handy back-tick operator doesn't work for this case either since they must be embedded in quotations to be recognized.

You're left having to assign the constant to a template variable if you want to use it as a dynamic lookup in an array which would then look like you expect:

$items[item].$ITEM_NAME

Makes some of the built-ins slightly less useful.
Back to top
View user's profile Send private message
okidoki_howie
Smarty Rookie


Joined: 16 May 2003
Posts: 8

PostPosted: Fri May 16, 2003 6:55 am    Post subject: Reply with quote

Thanks boots for you reply....

Hmm, i tried using "$items[item].$smarty.const.ITEM_NAME" because i set all my database columns name as constants... So when i change a column name i don't have to change everything in each page.

It's going to be a pain in the butt if i need to assign a template variable for each constant i use. Does anyone have any suggestions what i should do to my code?

Hmmm. i guess i can put all the constants in the config file too but i dunno.. Let me know what you guys think i should do..

Thanks
Back to top
View user's profile Send private message
sweatje
Smarty Regular


Joined: 17 Apr 2003
Posts: 70
Location: Bettendorf, Iowa, USA

PostPosted: Fri May 16, 2003 10:58 am    Post subject: Reply with quote

Did you realize this could be done in the template itself?

i.e.
Code:
{assign var=item_name value=$smarty.const.ITEM_NAME}
{section name=item loop=$items}
{$items[item].$item_name}
{/section}

_________________
Jason
jsweat_php AT yahoo DOT com
Back to top
View user's profile Send private message
boots
Administrator


Joined: 16 Apr 2003
Posts: 5611
Location: Toronto, Canada

PostPosted: Fri May 16, 2003 7:09 pm    Post subject: Reply with quote

@sweatje: yeah, but its a pain in the buttocks and it belies the fact that okidoki_howie already created a set of defines in PHP for that purpose.

Unfortunately, you can't even use config vars here as $my.sub.#key# is not allowed.

You might consider a template function that "extracts" field names into template variables.

On a side-note: I try to avoid having my field names appear in my templates altogether taking care of mapping issues in the PHP layer.
Back to top
View user's profile Send private message
okidoki_howie
Smarty Rookie


Joined: 16 May 2003
Posts: 8

PostPosted: Fri May 16, 2003 7:31 pm    Post subject: Reply with quote

boots wrote:

On a side-note: I try to avoid having my field names appear in my templates altogether taking care of mapping issues in the PHP layer.


To my torontonian Boots, Laughing

Ok, so you mean you just assign all the field names to template variables? So in my case, you would just assign all the constants to template variables?

I dunno, i've looked at some php projects and i rarely see them use constants for database fields. My professors at school always told us to use constants, which does make sense even though it's sometimes a pain in the butt.

Glad sars is out of the way=)
Back to top
View user's profile Send private message
boots
Administrator


Joined: 16 Apr 2003
Posts: 5611
Location: Toronto, Canada

PostPosted: Fri May 16, 2003 7:48 pm    Post subject: Reply with quote

I thought I would also suggest using a custom block function where you can hide the implementation details. This is especially true for the CVS version of the API which allows you to code your own block loops.

See:
messju's post to the dev list concerning the CVS change to blocks:
http://www.phpinsider.com/smarty-forum/viewtopic.php?t=291

foreach-like example:
http://phpinsider.com/smarty-forum/viewtopic.php?p=1564#1564

There are more examples on the forums if you do a search.

There are also other opportunities to get around your problem but the best choice is dependant on your application structure.

---

Just saw your reply to my previous post. My point in mentioning mapping is similar to the point of your prof: you want to abstract the field names away from the application. I tend to do so using a data layer between my db-backend and the application which queries the db on the backend and provides data objects to the application on the front-end. The application doesn't have to worry about the field names but it DOES have to worry about the object's fields passed back to it. That's okay, we're supposed to program against interfaces Wink

In other words, the idea espoused by your prof is a good one: abstraction. You just have to look at your tool chain to see which is the best way to implement that idea without too much overhead. In this particular case, using constants is probably not the least-effort approach considering your usage pattern.

Sit back and think again. You'll learn more about your tools and you will be better for it Wink

---

SARS: Bah!! That's just a snow-day for adults who don't have real problems to deal with. Sheesh. For people who don't know, it was reported here in Toronto as if it was the next plague when its really just a VERY BAD cold. You'd think a hockey town would be tougher.

Cheers from tDot
Back to top
View user's profile Send private message
okidoki_howie
Smarty Rookie


Joined: 16 May 2003
Posts: 8

PostPosted: Fri May 16, 2003 10:29 pm    Post subject: Reply with quote

Hmmm.... Rolling Eyes

Boots, when said "using a data layer between..." did you mean using something just to store the data, eg. in my case a bunch of constants?

I guess an array would be a better tool to use. For example, i can store all the column names of each table in the database in a seperate array. So i only need to assign a few arrays to the template rather than 100 constants. Am i on the right track or have u totally lost me? Wink
Back to top
View user's profile Send private message
boots
Administrator


Joined: 16 Apr 2003
Posts: 5611
Location: Toronto, Canada

PostPosted: Fri May 16, 2003 11:05 pm    Post subject: Reply with quote

@okidoki_howie: that's not what I meant by a data layer, but kudos on rethinking your problem -- your solution certainly would work. In your case you would have some sort of domain table in your db that mapped field names to output names.

In my case, I'm talking about abstracting the db backend altogether so that my application has no concept where the data is being loaded from. It talks to the data layer requesting things like the "user" object which gets returned with mapped fields.

The data layer is responsible for talking to the data provider and mapping the fields. In that situation, I can swap out the backend and replace it with something else. That "something else" doesn't even have to be a database--it could be the file system, a web service, an RSS feed, etc. I would have to make changes in the data layer, but the application remains unaffected since it never communicated directly with the backend. Also, since my data layer is written in PHP, I can use things like constants in that layer since they are well supported in PHP.

The application itself wouldn't use mappings--it would use the names returned by the fields of the data object. The contract between the application and the data is defined by the returned data-layer object, creating a type of API for the application. The idea is to strive to never change that front-facing contract. See where I'm going with that?

Compare that with SQL Views where instead of having clients issue queries directly against tables, they issue them against the view. Changes to the tables only require an update of the view -- client code remains unaffected as long as the view returns back the same fields it always did. In this simplistic case, the view is acting as the data layer, the table as the backend and the client code as the application. In the SQL world, stored procedures give a programatic approach to the same issue.

I'm not a professor (INAP), so I hope that makes sense Wink
Back to top
View user's profile Send private message
okidoki_howie
Smarty Rookie


Joined: 16 May 2003
Posts: 8

PostPosted: Fri May 16, 2003 11:45 pm    Post subject: Reply with quote

boots, i think i know what your saying now. If i'm correct, then my layering is similar. Here are the layers i have,

(1) smarty templates -> (2) web.php -> (3) lib.php -> (4) DB abstraction class

2. are my web logic scripts, retrieves/checks data and inputs, and outputs to smarty templates.
3. are my librarys (functions and classes) that i use to store/retrieve objects from my data source (mysql).
4. is just my database abstraction class to access mysql.

If i'm still not on the right track, then i think i need to see some code, but that might be too much trouble for you.

But anyways, in any layer model, you will still need someway to refer to the data passed between each layer. My first approach using constants was fine until i introduced Smarty into the picture. I guess i'll have to change it to arrays now, but before i do that, are there any other approaches? Or am i doing something wrong and i shouldn't need to do this?
Back to top
View user's profile Send private message
boots
Administrator


Joined: 16 Apr 2003
Posts: 5611
Location: Toronto, Canada

PostPosted: Fri May 16, 2003 11:57 pm    Post subject: Reply with quote

Yes, your layering is consistent with what I am talking about and IMHO it is a sound approach to take.

My question to you is this: why do your db field naming issues persist at the Smarty layer?

What I am suggesting is that the field names that your web.php layer provides back to your Smarty layer can be safely "hard-coded" into your templates. Why? Because if you change your db fields, you can change how they map to the application in your lib.php file (perhaps by changing your constant definitions). Your other layers need never be the wiser to the change.

Recall: each layer has only its own interface to its immediate higher and immediate lower layers.
Back to top
View user's profile Send private message
sweatje
Smarty Regular


Joined: 17 Apr 2003
Posts: 70
Location: Bettendorf, Iowa, USA

PostPosted: Sat May 17, 2003 2:40 am    Post subject: Reply with quote

okidoki_howie: I think this figure (from this Zend tutorial I wrote in 12/2001 ) describes what you have in place now.



However the idea of the data layer is missing in that diagram (the layer that would not need to change if your database columns changed). That is what I call Models in my applications, and here is a sneak peak at an upcoming figure from my June http://www.phparch.com/ article:



Even if you do not choose to implement your applicaiton as a MVC, you can drop out the controller layer and still get a lot of utility from the other remaining layers in your applicaiton. The Views are any PHP scripts that are performing assignments to your smarty object.

BTW: I tend to start with coding the field names into my templates. This is becuase we have a naming convention for our DB columns that is a standard where we work, so it makes sence to do so. However, by layering the application this way, you have a choice of how to deal with a column name change. If it only affects one template, you might choose to alter the template, however, if it affects multiple templates, you might instead just choose to iterate over the result set in your model and remap to the value the rest of your application is expecting.

HTH
_________________
Jason
jsweat_php AT yahoo DOT com
Back to top
View user's profile Send private message
okidoki_howie
Smarty Rookie


Joined: 16 May 2003
Posts: 8

PostPosted: Sat May 17, 2003 4:50 am    Post subject: Reply with quote

boots wrote:
My question to you is this: why do your db field naming issues persist at the Smarty layer?


This is going to sound odd, the issue persists at the Smarty layer because i used the same constant to refer to the DB coloumns and html form variables. Actually, i use the same constants through out all the layers. I guess i just got lazy and it that was a horrible design decision. Crying or Very sad

For example, i have a constant called ITEM_NAME that maps to the item name column in my DB. I fetch the item name from the DB abstraction class into my lib.php layer using the constant ITEM_NAME in my query. In my lib.php layer i store the item name in an array $blah[ITEM_NAME]. Then in my web logic layer i get the item name by eg. $instance->blah[ITEM_NAME]. See what i'm doing?



Now i see that i need to separate the mapping between layers... I guess i have a hard time figuring out what can be hard coded and what shouldn't be. Right now i use constants (yes, as mentioned the ones for my DB, since the fields are pretty much the same) for my html form variables in my web logic layer.

Should i just hard code the form input names in my web logic layer and smarty layer (ie. $_POST[html_var] and <input type="xxx" name="html_var">)?
Back to top
View user's profile Send private message
Display posts from previous:   
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Smarty Forum Index -> General All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group
Protected by Anti-Spam ACP