Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Scripting.Dictionary+Server.Execute problem

Status
Not open for further replies.

ASPVBNerd

Programmer
Nov 23, 2005
83
SE
I am trying to have my website as a multiple languages
I would like to get all language settings in 1 connection to the database.

I am using Dictionary to add all the languages to diction.
My problem is that I am using Server.Execute to Execute the page contact.asp and when i use Server.Execute i loose my dictionary that i used in my default.asp and cant use it the contact.asp
This is my code in the default.asp
Code:
Dim Diction
language = "Swe"
Set Diction = CreateObject("Scripting.Dictionary")

Set ObjRecordSet = Open("Select Lang, LangNo, Info From tblWebsite Where Lang={0} Order by LangNo", Array(language))

While Not ObjRecordSet.EOF
    intTemp = ObjRecordSet.Fields.Item("LangNo")
    strTemp = Trim(ObjRecordSet.Fields.Item("Info"))
    Diction.Add intTemp, strTemp
    ObjRecordSet.MoveNext
Wend
ObjRecordSet.Close
Set ObjRecordSet = Nothing
In my default.asp when i want to display my info i use it like this <%=Diction.Item(8)%> and this work as long as it is in default.asp

If i use Server.Execute("contact.asp"). In contact.asp i would like to show the info from the diction that i looped and added it from default.asp <%=Diction.Item(9)%> but it doesnt work, the error message i get is object required.
I know that I am missing this line in contact.asp
Set Diction = CreateObject("Scripting.Dictionary")

Hope you understand what i mean.
 
Since you are creating and filling the Dictionary object in your first page, the second page does not have access to that variable (scope).
The easiest solution would be to dump it into a Session variable, at which point you would be able to access it from anywhere in your site for that one person. The downside of this is that session variables are stored in memory and if you don't explicitly abandon the session it doesn't end until 20 minutes after the user requests a page (by default). So your loading a bunch of ActiveX objects into memory and, depending on your hit count, that could degrade performance a bit.

Another option, besides using a dictionary object, would be to simply use ObjRecordSet.GetRows() to return the data in a two dimensional array. This will be faster than transferring it to a dictionary object and have less overhead.

-T

barcode_1.gif
 
I don't think this is what you want to hear, but..:

[URL unfurl="true" said:
http://www.15seconds.com/issue/010220.htm[/URL]]
One drawback to Server.Execute is that it can't call a particular procedure on the included page. Server.Execute starts running code at the top of the executed page and continues running the code until the executed page ends, at which point it returns to the original page. Another potential drawback with Server.Execute is that any page-scope variables are not shared between the original page and the executed page. With server-side includes this isn't an issue because the include file code is incorporated into the original page before it is executed. Regardless, there are many situations where using Server.Execute is a better choice than using server-side includes.

In other words, your 'Execute'd page doesn't know about the calling page other than the querystring and form values.

Maybe it would be better for you to include a standard language method within the target page which works off of the Session variable to get the preferred language (e.g. "swe")

So, an include file such as getLangSet.asp sits in each target page which would contain the code that generates the scripting object instance inside your target page. Include files act as part of the calling page, so you should have access to the variables you are creating.



A smile is worth a thousand kind words. So smile, it's easy! :)
 

Ah, Tarwn beat me to it.

As a comment on your suggestion Tarwn, I would not recommend using the Session to store the Dictionary object... as it's threading model can limit the scalability of the site and potentially cause problems.

Also as Tarwn mentions, your current method seems a bit inefficient, for every page you connect to a database then iterate over the recordset object to create a dictionary object. Three expensive operations.

Unfortunately ASP is limited somewhat in this area.

One option is to create language code pages that have the variables / dictionary object hard coded - so /inc/lang/swe.asp is hardcoded like:

Diction.Add "field1", "My Field"
Diction.Add "field2", "My other Field"
or
fld__field1 = "My Field"
fld__field2 = "My other Field"

The second option would probably be more efficient - especially for smaller number (hundreds) of variables. Though I've not checked this, so may be worth testing.

Then you can use Execute and FSO to read the file and execute the vars dynamically (based on the users preferred language) meaning that every page will have these values available to them.
To make it slightly more efficient, you could have language sets per page, so you only load the vars/translations you need for that page... however the tradeoff with that option is maintenance and manageability...

Another method could be to do a mixture of Tarwns suggestion above with some serialisation..

On first starting the application or whenever you feel appropriate, load the array set from the database based on the users language set. Use GetRows and store the array inside the application object against the code for the language (that way you only have them once in memory, instead of for each user). On each page request then loop through the array once and using Execute create variables from the array as per the above method - this means that you only loop through the array once (rather than for each field). It may make is more efficient (and kinder on memory) if you only create vars for the fields you need inside the page - so some kind of check list and use of InStr might help extract those relevant to the current page... test the performance on this though.. I'm not 100% sure which would be more efficient.

There are other ways, but the essence of the options are:
- store the language sets in memory (faster, but watch your memory usage)
- store them only once
- iterate over them as little as possible by making the values directly accesible.
- create only relevent variables (as few as possible per page)
- do not use Dictionary objects in Session or Application

Hope that helps,

A smile is worth a thousand kind words. So smile, it's easy! :)
 
Would like thank you for the responds.

Know i know that the info that i stored in a dictionary would follow me to the second page.

Storing the info in a session is not an option because it doesn't seem to be a good solution.

I have tried to use GetRows at default.asp but same problem with dictionary
At the top i use GetRows
Code:
language = "Swe"
England = "English"
Sweden = "Svenska"

Set ObjRecordSet = Open("Select Lang, LangNo, Info From tblWebsite Where Lang={0} Order by LangNo", Array(language))
ArrRows = ObjRecordSet.GetRows()
ObjRecordSet.Close
It goes okay do it like this with getRows <%=ArrRows(2, 6)%> but it doesn't follow me to contact.asp

I like that solution that i could server-side includes
If i do server-side includes solution do have to include the language for every site that i use Server.Execute?
 

Re-Read my post above.



A smile is worth a thousand kind words. So smile, it's easy! :)
 
I'm also in the process of changing my current language selecting procedures, I have it setup like this;

I use XML files, one xml lang per calling file or block of code, this works alright, however as you have like 10 blocks of code, it has to process 10 xml lang files, so I've been thinking in using the Application object, it should be populated at the beggining of the page processing, and then available throughout, however, I want it to be populated only once, otherwise this is done on every page load or refresh, I'm thinking on using a flag to mark if the application object is already populated and ready to be read from, and if so, it won't be populated again, the only drawback is if you make changes to the lang variables, they won't show, untill the aplication is populated again.

What would be the best method to flag? I'm thinking on using a session var to hold the value, is there a better way? Or, is there a better way all together?

Is it faster to use a big single xml file or use several smaller ones? Also, what is faster, getting data from xml or from a database?

Thanks.
 
theScien,

In your situation, I would recommend:

1. On Application_Start in the global.asa, load each XML document into memory (application variable) separately and name them with their coded language name (e.g. en,fr,es,de).
2. On each page call Load the XML from the application variable that corresponds to the language you want (e.g. oXML.LoadXML(Application(Session("lang")) ), then use XPath to extract the values that you want (e.g. "\\ref[id='abc']")
3. The Session("lang") value should be populated on the start of a session - you could select this from user input or default from their user_agent string.
4. If you update the XML files, simply load them into the appropriate application variable again... you could knock up a quick and dirty page to read from the file, display it in textarea and then save from the POST back into the app var.

You may want to look at this thread though...
thread333-1155202
There are different things to make multi-lingual - you might need to consider which level you want to take this to.

As per your second-to-last question,... The smaller the data to be read, the more efficient it will be. however the less I/O you do the better. As each user will only want to see one language at a time I would recommend 1 file per language. But I would prefer to have it in memory - it will be many times more efficient - you just need to keep an eye on the memory usage.. but in most cases this is not an issue.

As per your last question, well that depends greatly on a lot of things. Complex queries, filters etc etc are usually faster on high-performance databases than XML data, which usually makes relationships between sets more cumbersome for the processor. It is also faster for large datasets.. millions of rows in XML would perform slower than the same in a database... however, for simple, smaller sets of data, XML is probably a better option - the IO read, parse and extract steps are relatively inexpensive actions in comparison to network connections etc (though dark fiber between app server and database server or local db would remove that issue). If you can store the XML in memory then this is even better - but again, this is only for a relatively small number of rows (1000's not millions..).

I usually use XML for my menu systems, allowing me to set permissions, actions, links, settings, etc etc and use that to extract the specific menu items for the user in question. These are all stored in XML in the application variable, and perform very well. This was a choice of functionality over performance, as a static menu would obviously be faster.

On XML, I tested out a page a while back that used 2 methods for creating a list of items in a specific format. The database retrieval was the same in both counts (getrows). The formatting in method 1 was done by iterating over the array and outputting the formatted content - I used a fast string concatenation class that speeds up string building by a factor of more than 100 for large datasets. The second method serialised the array into XML and used XSLT to transform into the output. As you can imagine, the second method was slightly faster (~10%) for small number of rows(2/3/10) but MASSIVELY faster for higher number of rows(300/1000) - more than 10x faster...

The choice, as they say, is yours...

A smile is worth a thousand kind words. So smile, it's easy! :)
 
Go damber :)

Yeah, I wasn't suggesting the dictionary object in a session variable as a _good_ solution, simply mentioning as a possible solution (though one I wouldn't suggest using).


barcode_1.gif
 

Tarwn,

Yeh, I realised you weren't - but thought the user might think it was an easy way out and find problems later (mind you it is still an option). It was actually the first thing that popped into my head too - but then I remembered that ASP has a few 'features' in this area... ;o)







A smile is worth a thousand kind words. So smile, it's easy! :)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top