Closed (fixed)
Project:
Currency
Version:
6.x-1.x-dev
Component:
Code
Priority:
Normal
Category:
Feature request
Assigned:
Unassigned
Reporter:
Created:
2 Nov 2008 at 06:12 UTC
Updated:
8 May 2009 at 08:19 UTC
Jump to comment: Most recent file
Comments
Comment #1
kbahey commentedWhy don't we just have a centralized currency formatting function, that is also themable?
This way, you can override the value in the theme any way you like, and do away with the decimals if you want, or add the symbol if you want, ...etc.?
Comment #2
johnhanley commentedA theme function is a good idea, but it seems like we'd still need a predefined way to determine the decimal count for each currency.
Besides the decimal count issue, it would also be nice to have a way to customize the currency output. For example when displaying negative amounts, I would like to use the format -$200.00 (the way PayPal does it) instead of $-200.00. The PHP function money_format might be useful for this purpose, but I haven't played with it enough to know for sure. Perhaps sprintf is more suitable.
Comment #3
kbahey commentedThat is what I am saying, a unified way to output the currency is a theme_currency($symbol, $amount) function that can be overridden.
Inside that we can use money_format() by default with no side effects since it is in PHP 4 and 5.
Any patches?
Comment #4
johnhanley commentedI haven't thought the idea through enough to create a patch. Can you think of any existing theme functions that could serve as an example?
Comment #5
kbahey commentedExample from user.module:
You call it like this:
So, you have to define the following function in the module.
Then call it via:
Then to override it, you create a function called phptemplate_currency_amount() in the template.php of your theme, and it will override what is in the module.
Read more about theming as it is explained in far more detail.
Comment #6
johnhanley commentedRight, right. I've created many theme functions and have overridden preexisting ones in template.php, but I hadn't given the idea adequate thought yet.
Your post is a good start and now has me thinking. It appears we have 4 parameters:
amount
symbol
decimal
code
The only required parameter is amount. The others could default to
The default output would be: $100.00 USD
Implementing money_format would require setting the category and local parameters with setlocale, which might end up being more effort than is needed.
Another option would be to have some additional admin settings. For example the way Windows Vista allows the user to control the currency display.
While all of this is very interesting it still doesn't address my original question, which is how to set the decimal count for individual currencies. Perhaps something like this would suffice:
For that matter why not combine all the elements:
Comment #7
kbahey commentedYou are on the right track.
Think about it for some time until it firms, and then make a patch.
Also, it would be nice to use format_number() inside the the theme function.
As for the number of arguments, we should consider making it a keyed array, instead of having 4 arguments. And we can check if the argument is not an array, then it is only the amount and we act accordingly.
array(
'amount' => $amount,
'symbol' => '$',
...
);
As for the original question, the whole idea is not to clutter the module with special cases.
Now, on your site you do this in template.php:
Countries using comma or period for thousands separators can use whatever they like.
Comment #8
johnhanley commentedI hear what you're saying about clutter, but each currency's characteristics is absolute and not subject to change so it makes sense to include a decimal count definition in the base module. Grant it most decimal count values will equal '2', but I believe this is more efficient than hard-coding conditions for individual currencies. You can then simply use the decimal count variable with number_format() like so
Comment #9
kbahey commentedI am taking the "less code" approach.
Most currencies just work right now, and only a minority need this feature.
So, having those few sites that use those minority currency override things in template.php makes the module leaner for everyone else (the majority).
I am against creeping featuritis and bloat and try to avoid adding code for less used features.
Less code is better code ...
Comment #10
johnhanley commentedI don't think adding an extra element to an existing array is "extra code". Storing the decimal count property with each currency is the way most financial and e-commerce applications do it.
I suppose it depends on one's perspective. In this case less code at the module level means more code at the template level. In its purist form the template level should contain the least amount of business logic as possible.
Comment #11
kbahey commentedAdding the extra field makes the array bigger and consume more memory. It also makes it added work to maintain in the future (more elements, prone to editing).
Perhaps if we move the currency info array to a database table that is created on the module install, we can add that extra field, without being too concerned with memory usage. We can provide a default theme function that will cater for all currencies, yet will still be overridable for those want to do so.
Comment #12
johnhanley commentedI actually share your concern about bloat. In fact currency_api.module is only one of two (literally) third-party modules currently enabled for my custom application. The rest of the functionality is produced with a small suite of custom modules. No CCK, Views, OG, etc. As a result the application screams. If the concept proves successful (i.e. tons of traffic) I will need to preserve every possible cycle.
Somehow many Drupal developers have come to accept and even embrace 100's of database hits per page load. For this reason I like the idea of keeping the currency information in memory. This makes the most sense to me because the information is unlikely to change very often. Besides your module is extremely light so memory usage is negligible.
That said, it's your call.
Comment #13
kbahey commentedOK, roll a patch with the added field in the array and a theme function to display the stuff.
Then measure using devel's performance module and see the difference before and after.
If it is negligible, I will accept it.
We need the patch to go in for 6.x later.
Comment #14
johnhanley commentedHere's the patch as discussed.
Included in this patch:
function currency_api_get_currencies(), returns an array with combined attributes currency symbol, name, code, and decimal count.
function theme_currency_api_amount(), returns a formatted string using attributes of a currency, example: $200.00 USD
Note: currency_api_get_currencies() contains the latest Yahoo currency list as of 11/01/2008. The old functions currency_api_get_symbols() and currency_api_get_list() are now depreciated, but have been preserved.
The following function illustrates how to cache the currencies array and return the attributes for a currency...
Example usage:
Comment #15
kbahey commentedThe patch does not apply.
Can you please make sure that patches are created against CVS, with the tag DRUPAL-5, or the 5.x-1.x-dev tarball?
Comment #16
johnhanley commentedAgainst 5.x-1.x-dev tarball.
Comment #17
kbahey commentedStill needs work.
We have two functions that return currency information:
The old one is currency_api_get_list() which returns the code and name, and new one is currency_api_get_currencies() with code, description and symbols.
There is also currency_api_get_symbols() which can be folded into that too.
Having data in many places is a bad thing. Better unify them all in one place, so maintenance means just one place to change.
Also, we need to do this to 6.x-1.x-dev when 5.x is done.
Comment #18
johnhanley commentedThanks for the coding practice tip, but did you read my previous comment?
currency_api_get_currencies() COMBINES the attributes of both currency_api_get_symbols() and currency_api_get_list() PLUS adds the currency decimal count.
The old functions are intended to be deleted, but this needs to be communicated to developers so as not to break their applications.
Comment #19
kbahey commentedI am inclined just to break the API, and make this 5.x-2.x-dev and document that the old functions do not exist. This is what Drupal core does to stay lean: break the API, and document the changes so people can migrate.
We can document the API in the README.txt file as a new section that lists the functions to be used.
Alternately, Can't we just change them into wrapper functions? Internally they call the new function and return only the needed info from the big array.
I prefer we cleanup the API and create 5.x-2.x-dev.
What do others think? Hopefully we get some comments.
Comment #20
johnhanley commentedYou could create a wrapper function to pull in the various attributes and combine them into one array, but if the goal is to streamline the API and ease maintenance then the new single function defining all the attributes in "one place" is the way to go. This, along with the theme function, give me the desired flexibility.
Yes, input from other using the API module would be helpful.
Comment #21
johnhanley commentedHere's the latest (last?) patch related to the above changes.
functions removed:
currency_api_get_list()
currency_api_get_symbols()
functions added:
currency_api_get_currencies()
theme_currency_api_amount()
function modified:
currency_api_get_desc()
Now everything is defined in one place.
Use the previously described wrapper function in your custom module to return all attributes (code, name, symbol, decimal) for a given exchange rate code. The wrapper function also has the added benefit of static variable usage, which eliminates the need to redefine the array for subsequent calls.
Interest parties are welcome to further refine/enhance these modifications.
Cheers,
John
Comment #22
kbahey commentedI noticed the patch is against an older version
Can you please reroll against the last version?
Also, can you include in it updates to API.txt to reflect the latest API?
Comment #23
markus_petrux commentedSweet addition. I'll be using the decimal count for the Money CCK field :)
#217842: Format currencies according to their own custom, add hints for this to the Currency API
Comment #24
markus_petrux commentedWould you mind checking the attached patch?
It implements
currency_api_get_currencies()as in previous patches, but then it keeps the current APIs reusing the array that is provided by the new API, so the data is just stored in one single place and it offers backwards compatibility with existing theird party modules that depend on the currency api.For the theme function... I would suggest taking the Format Number API into account here as well, since it provides a method to define thousand separator and decimal point symbols. Anyway, this thing could be provided on a separate patch if needs be, maybe?
The attached patch would be enough for the Money CCK field to reuse the decimal count settings per currency.
BTW, the patch here is against the -dev package for D6.
Comment #25
johnhanley commentedGood call on keeping the existing API functions as wrappers for backwards compatibility.
I wouldn't recommend creating a dependency on Format Number API, but it's a nice option for those who want to override the default theme.
Comment #26
markus_petrux commentedhmm... maybe it is not really the best place here to provide a theme function for currency amount?
For the Money CCK field I would happily use the new API with information about decimal places per currency, as an option, but not the theme function as it doesn't really fit the needs of the field formatter, and I prefer using the Format Number API for the amount.
Comment #27
johnhanley commentedWell, you can always choose not to use the default theme or it could be struck from the patch altogether. Since users needs greatly vary when it comes to formatting currency it's nearly impossible to have a one-size-fits-all theme. currency_api_get_currencies() contains all the attributes needed.
Comment #28
markus_petrux commentedWould it be possible to review the patch in #24 and discuss the theme function after that one gets in?
Comment #29
kbahey commented@markus_petrux
I am ok with the patch in #24.
However, do we really need a separate module to implement a theme function? I think it is kind of overkill with more dependencies, more things to maintain/upgrade, ...etc.
I can commit #24. But would like to know your (and others') views on a 3rd module dependency. Rather add a theme function in currency_api, even if the other module can enrich it by overriding the function. So we have a basic function that is suitable for most people in currency_api, and those who want to be more fancy can install the other module.
Thoughts?
Comment #30
markus_petrux commentedOk, thanks for taking a look at this. :)
Here's a new patch that includes #24 + the theme function in #21 + doxygen for functions where it was missing.
Comment #31
johnhanley commentedI second the idea of including theme_currency_api_amount() in currency_api. It provides basic output and can easily be overridden. It also serves as an example, but obviously won't satisfy everybody's need (just like any other theme.) For instance someone might want to format with sprintf.
Comment #32
kbahey commentedCommitted.
Thank you!
Comment #33
markus_petrux commentedThanks! :-D
Any chance for a new release?
Comment #35
markus_petrux commented@kbahey: Could you please create a new release so that the changes introduced here are included on a official release?
Latest Money CCK field needs this, and an official release here would save a few headaches to users. Please?
Thank you :)
Comment #36
kbahey commentedmarkus_petrux, I granted you CVS commit access to this module, since you are a long time contributer to Drupal.
You can go ahead and create a stable release yourself. Be sure to run the cvs release notes script.
Close this issue when you are done.
Comment #37
markus_petrux commentedKhalid, thanks for the confidence. Though, I had some trouble creating the release: #455380: Request to fix or delete a failed project release. I hope it can be fixed asap.
Comment #38
markus_petrux commentedRelease node has been fixed! :-D