Dynamically create variable in Thymeleaf - variables

I have an object in ${object} and a string in ${attribute}.
for example, the object may be a "user" and the attribute may be "email"
Now I want to access ${user.email}. However this needs to be dynamic as it should also work for ${article.name} and whatever else.
I tried following concatenations, but none of them worked
${__${object.attribute}__}
${__${object}__.__${attribute}__}
${__${object}__+'.'+__${attribute}__}
${${object}+'.'+${attribute}}

You can use this:
<div th:text="${object.__${attribute}__}"></div>
Assuming you have a model containing the following test data:
User user = new User("John", "john.jones#foo.com"); // user has name and email
model.put("object", user);
model.put("attribute", "email");
That will generate:
<div>john.foo#bar.com</div>
The only place where you need to use the preprocessor __${...)__ is the attribute variable.
After preprocessing has been performed, you will be left with the following Thymeleaf expression:
<div th:text="${object.email}"></div>
That will then be processed in the usual way to generate the HTML you need.

Related

How to store logged user in Odoo14

I am trying to store the currently logged user into a many2one field using compute method. It's working fine if i define the Mnay2one field without the store="True" parameter. Actually, i need to save it.
Here is the code:
def get_logged_user(self):
for rec in self:
print('inside get_logged_user---------------',rec.env.user.name)
rec.logged_user_id = rec.env.user.id
logged_user_id = fields.Many2one('res.users',string="Logged user",store=True,compute="get_logged_user")
EDIT:
If you only need to control visibility of a field/button inside QWeb view you could archive this without dedicated field. You could use context.get('uid') to get current user like this:
<button ... invisible="context.get('uid') == assigned_user_id">
But if you need to store logged-in user inside a field you could use default instead of compute.
Something like this:
logged_user_id = fields.Many2one('res.users', string="Logged user", default=lambda self: self.env.user)
Note usage of lambda function.
If you really need to use compute field with store=True you need to specify when to compute it. By using api.depends decorator you can trigger it when your_field is changed.
#api.depends('your_field')
def get_logged_user(self):
But I would ask a question why do you need to store logged-in user inside a field? If you could provide more context maybe we could suggest different solution.

Saving Sequelize Query Text In Database

I have a sequelize query that I would like to save in a database and then execute on demand. In order to do this I am first testing how this would work in a variable as a string (because in a database it will be stored as a string):
queryToRun = models.user.findAll({
attributes: [
['name', 'name'],
[Sequelize.literal("COUNT(DISTINCT(user.id))"), "user_count"]
],
group: Sequelize.col("user.name")
})
With this query I would like to use it like so:
Promise.all(queryToRun);
I am successfully able to save the object (object that goes inside findAll with the attributes etc) as a string and then execute, but I can't figure out how to save every part of the query. I want to save the actual "model.user.findAll()"string and evaluate it at a later time.
This is important because I want to define the model that I need to run findAll on and save it in the database.
This is actually fairly simple
Don't use the multiline string it trips up the function call for some reason
Use eval to evaluate the string
Example:
let queryToRun = 'models.project.findAll({})';
Promise.all([eval(queryToRun)]);

web2py check password in form

I am trying to create a change password form in web2py. I am using db.auth_user table. I want to create a form with fields ['current_password', 'new_password', 'repeat_password']
Form should give a warning to user if the password is not entered correctly.
My code is:
request.vars.current_password = request.vars.current_password if request.vars.current_password else 'xxx'
user_password_form = SQLFORM.factory(Field('current_password', 'password',
requires=IS_EQUAL_TO(db(db.auth_user.id == auth.user_id).select('password').first().password)(
str(db.auth_user.password.validate(request.vars.current_password)[0]))),
Field('new_password', 'password'),
Field('repeat_password', 'password',
requires=IS_EQUAL_TO(request.vars.new_password,
'Passwords do not match')))
I have tested the validation for the following code and it sets a=1 if password is entered correctly. But on the form validation I couldn't figure it out how to implement it
if request.vars.current_password:
if db.auth_user.password.validate(request.vars.current_password)[0] == db(
db.auth_user.id == auth.user_id).select('password').first().password:
a=1
Any ideas how password validation can be achieved?
The web2py Auth system includes a built-in password change action. If you are using the default user action in the default.py controller, you access this form via /myapp/default/user/change_password.
If you prefer to create a separate controller action just for this purpose, you can simply do:
def change_password():
return dict(form=auth.change_password())
and in the associated view:
{{=form}}
Regarding your custom code, you cannot use the IS_EQUAL_TO validator alone, as it takes an expression that must be equal to the value submitted with the form (you cannot call the validator with a transformed value as you have, as that will return a tuple, but the requires attribute must be a callable object that takes a field and a value).
Instead, you could use the CRYPT validator followed by the IS_EQUAL_TO validator in a list -- the first validator will transform the submitted password to a hash, and the second will then test for equality with the stored password hash.
Alternatively, you could use:
def check_password(password):
new_hash = db.auth_user.password.validate(password)[0]
return new_hash == auth.user.password
form = SQLFORM.factory(Field('current_password', 'password')
requires=IS_EXPR(check_password)),
...)
The IS_EXPR validator can take a function that will be passed the value, and the function should return True or False (note, this usage is not documented -- the book only shows the alternative usage, where you provide Python code as a string, which will be exec'ed).

Use Instance method instead of Database field while accessing in Rails

I have database field called name. And i have used user.name in my application. Now I have something like salutation which i wanted to append with the name. So what i basically want is when i am accessing name via user.name it should fetch the value from instance method rather then database field.
def name_with_salutation
"#{salutation} #{name}"
end
So when i am accessing name via user.name it should respond with user.name_with_salutation. I have tried alias_method but it shows stack level too deep because name is getting used in name_with_salutation so it got stuck in infinite process.
I am trying this because i do not want to replace name with name_with_salutation throughout the application. This should not apply when i am assigning values user.name = "abc".
Please let me know, How this will be done.
To overwrite an original Model method, you can write a method with same name, and then use read_attribute(:attr) to represent the original attribute value.
Given name attribute exist, to overwrite #name:
def name
"#{salutation} #{read_attribute(:name)}"
end

Insert data from DB to URL manager

I want URL manager to process URL with the company name with my CompanyController. To do so dynamically I should get company names from my database.
Now I have such rule (but it's not dynamic):
'<alias:(vector|karnasch|tecnomagnete|ruko|bds-maschinen|exact)>' => 'company/view',
(vector|karnasch|tecnomagnete|ruko|bds-maschinen|exact) --> data to this line I want to get from database.
I can get this data (manually establish connection to db), but maybe it's another more beautiful solution with help of Yii functional. Thanks!
You can always create your custom UrlRuleclass. If you only want to parse incoming URLs you can simply return false from the createUrl() method. In the parseUrl() method you query the DB for your company names and inspect if the current URL matches. If not, you simply return false again.
Well, you don't need to do this, you just have to define the right pattern, e.g. :
'contact' => 'contact/form',
// other rules should be set before this one
'<alias:[-\w]+>' => 'company/view',
http://www.yiiframework.com/doc/guide/1.1/en/topics.url#using-named-parameters