Hi,
How do i add calculations to my website?
views_calc is too limited and computed field seems to have a scope on the specific content-type your are creating.
Should i create a custom module, what is the best approach?
Details:
I'm building a sports team site that needs some calculations. For example it needs to calculate the total payments of a player. That needs to be substracted from the total spendings of the team in general. There's are some factors that influence the the calculations, for example the percentage the player is participating. So in a spreadsheet this would be some calculation referencing various different values all across the spreadsheet. Now i like to do this in drupal. I have no problem with coding it myself, but i'm curious about suggestions on how to start. I will also checkout views_calc from cvs to see if its worth extending.
Thanks,
Bram.
Comments
You can probably just use PHP code
You can probably accomplish this with PHP.
For example, let's say we have a content type called "players" with 2 fields - "field_2009salary" and "field_2008salary". Let's say we want to show how much the player made in 2008 and 2009 combined. Here's what you'd code into your node-players.tpl.php...
(And don't forget to add an entry in your template.php to register that template with your theme registry.)
You'll have to look at PHP documentation to figure out the functions you'll need, but it's all possible.
And if you want an easy way to view all of the data you have available to you (and all the field names), install devel module and then in node-players.tpl.php, put this code:
Calculations cross content-types
Thanks for your reply. And how do i do this cross-content-types? For example if have the following content types:
1. players (list of players in the team, names, phonenumers etc.), for example player i want to calculate their
2. spendings (description, amount) this is a list of spendings of the team
3. payments (playerid/reference, date, amount) specifies each payment of a player in the team
Now i'd like to compile an overview with the following columns
1. player,
2. total payments of this player,
3. total spend divided by number of players in the team,
4. balance of this player (= payments - spend).
See an example (in Dutch): http://www.bierpotonline.nl/bierpot/overview.php
Kind regards,
Bram.
A little confused, but here's my take...
I'm a little confused about the structure of your content types, but here's what the structure should be:
(Note: use CCK to create these content types)
The 4 content types:
-player
-team
-payment
-spending
The fields within them:
-player: player name, spendings (node reference to spending nodes), phone number, etc.
-team: team name, players (node reference to player nodes), payments (node reference to payment nodes)
-payment: date, amount
-spending: description, amount
Then, on the team content type's template (node-team.tpl.php), you'd use the node_load to gather all the data that is linked through your node reference fields. Follow this method here: http://drupal.org/node/195246#comment-1849342
Then once you have all the relevant data loaded, it's just a matter of some simple arithmetic. PHP can do simple arithmetic just like you'd expect. For example if you say
...then you'll see this:
Just check with some PHP documentation online (lots of sites explain PHP) for functions like dividing (I've never divided with php).
Reference bottom-up
Hi,
Ok, i get access to the fields on the other content-types. But i was wondering...you pointed out to include 'team' with refences to 'players' and 'payments'.
I had all those content-types created, but originally did it the other way around: players and spendings referencing team (that seems logical to me because a team node is only created once at the beginning (before players and spending nodes).
So is there a similar way to find all spendings of a certain team?
Would it be an option to create a view that outputs all data of a team (players, spendings, payments). And to code something to relate them to each other and do the needed math? How would that work?
Kind regards,
Bram.
Yes, you can do it like that
Normally, yes, the proper approach to a 1-to-many relationship would be to put the relating field (the foreign key) into the "many" table. This means that the traditional way of doing this would be, in fact, to put the node reference field within the payment and player content type. But, in Drupal, I've found it's a little more convenient to do it the other way around because it's easy to display referenced information on the team content type if that's the content type that has the node reference fields.
If you want to do it the 'proper' (traditional) way, though, then yes you can put the node reference fields in the player and payment content types. You'd then have 2 ways of extracting this information. The first would be to use a view like you mentioned. Views has 'backlinks' functionality built-in. Take a look at the "backlinks' view that comes with Views by default for an example. The other method would be to use the Node Referrer module. It's essentially the reverse direction of a Node Reference field. Every time you add a node reference in a player node to a team node, for example, it automatically adds an entry in the team's node referrer field that basically says "this player referenced this team".
Backlinks doesn't do it unfortunately
Thanks for pointing me in this direction. I just tried backlinks in views. Nice functionality, but i don't think it fullfills my need. It works based on the search indexing, so it only creates the links when the indexing process has run. And i want to have it instantaniously. Now i'm going to try Node Referrer.
Note to anyone giving backlinks a try. First enable the Search module if you hadn't already and run cron.php. Then enable the backlinks view in the Views list or you can add the Search - Links to in the Argument section.
Node referrer works good, what are my next steps...
Node referrer works very good. I have four follow-on questions though.
I can not access the nodes content as you specified, as the items are in another array, this will work:
$noderefnode = node_load($field_payments_backref[0]['items'][0][nid]);So adding ['items'][0] at the end. Ofcourse this only gets the first node.
1. Is there a way to get them all with the node_load function?
How do i proceed from here?. I'd like to create an overview page which is read-only and builds up an overview as seen in link in the beginning of this post.
2. Should i create a content type 'overview' for that with all the referrers on it?
(isn't that a bad habbit to build a content-type just to show something? doesn't really matter me if it gets the job done, but i'd like to understand what the 'right' way would be).
And now that i have the data in the template, how should i continue?
3. Do i add the math code in the template do it is populate with all the values that i need? And..
4. Should i than do some theming tricks in node-overview.tpl.php to create a custom gui?
Thanks again for your support!
Kind regards,
Bram.
computed_field
have you try this module instead? http://drupal.org/node/290443
i'm looking for something similar
Don't think that works, but it led me to CustomPage and Panels
I don't think that would be a solution to my problem. But i don't really understand how this sort of problem should be handled in Drupal. But through the link i found CustomPage which might be a good alternative to creating an overview node. And that led me actually to Panels which i intended to look at later anyway.
So i'm not sure if you can mix and match content-types with Panels, but will try that out and otherwise CustomPage.
Answers...
The original method I explained was for accessing the values within a node reference node. Because you're trying to extract from the other side of that relationship (from the node referrer field), my original method will not work, as you have discovered with your correct code. Here's' how to extend your code to extract all of the values in that array...
To answer q#2, it was my understanding that you were going to have the user view this data when they view the node for a team. If so, you can just modify node-team.tpl.php. There are probably other methods too.
#3: Yes, to do math you can do it right in your template and php will spit back the answer to you. I'd envision you using some sort of foreach loops like I have above to give you temporary variables that you can then use in math formulas. While in a foreach loop, you can add information to an a new variable (an array) that will then be available to you after the foreach loop. (for example, the $backrefnodedata array that I created above now has all of the back ref node data for me, even though none of that content was present before the foreach loops).
#4. Yes, you can do that (if you choose the node-overview.tpl.php route). You can do that in combination with css tweaks. As for the "right" way to do this from a traditional database architecture standpoint, the 'right' way would be to use queries to extract the data. Views is basically a query builder, but I've never used it for math so I wouldn't know how to direct you in that regard. But, essentially the reason all that data is available to you is because your mysql was queried for the data by the node referrer field, so I think that node-WHATEVER.tpl.php customization approach is just fine.
Views does seem to be a good alternative
Creating a content-type just for displaying data doesn't seem to be the right way to me. So i did some research in theming views. And it actually seems to provide a good alternative, which as far as i can see right now is the right way to handle this issue.
It is quite simple, only the accessing of variables in a view theme is sometimes quite hard to figure out. You can not easily do calculations because all fields are marked up already with HTML. I had no problems accessing the raw query variables on the 'field' level (views-view-fields--Overview.tpl.php). But as i needed the raw result of the whole query i needed it on grid or page level (views-view--Overview.tpl.php). On that level all i could find was query results that were already marked up with html from lower level templates. But eventually i did found out how to do it (see last resource at the end of this response).
In short.
1. I created a view that lists all payments and spendings of the team.
2. Than i've overwritten the view template with views-view--Overview.tpl.php
2. And included the following test code:
I think this would provide me the convidence that all type of calculation are possibles.
Handy resources i used:
View theming basics: http://mustardseedmedia.com/podcast/episode23
Views row theming: http://mustardseedmedia.com/podcast/episode30
Retrieving raw variables: http://www.appnovation.com/over-riding-views-2-queries-drupal
eink21, hope this helps you and others as well.
Kind regards,
Bram.
Thank you
This was just what I was looking for.