i am using wtforms with flask framework. when i use DateTimeField i add format parameter.
But datetime format is coming from user which is logged in
forms.py
from flask import g
from wtforms import *
import wtforms.validators as v
from flask.ext.babel import lazy_gettext as _
from flask.ext.babel import npgettext as _n
from app.app import app
from app.base_forms import *
from app.modules.post.models import *
class PostForm(BaseForm):
post_date = DateTimeField("Post Date", format = app.config.get("DATETIME_FORMAT"), validators =[v.Required(message=_("Post date is required"))] )
i set value of app.config.get("DATETIME_FORMAT") on before request
#app.before_request
def before_request():
if g.user.language == "tr"
app.config["DATETIME_FORMAT"] = "%d.%m.%Y %H:%M"
else:
app.config["DATETIME_FORMAT"] = "%m-%d-%Y %H:%M"
my application structure
/app
/modules
/post
/controllers.py
/forms.py
/models.py
/app.py
/run.py
content of /app/app.py
from flask import Flask, url_for, g, request, redirect, render_template
app = Flask(__name__)
app.config.from_object('app.config.config.ConfigDevelopment')
# Import Modules
from modules.post.controllers.admin import module as modulePostAdmin
app.register_blueprint(modulePostAdmin)
# other codes here
#app.before_request
def before_request():
if g.user.language == "tr"
app.config["DATETIME_FORMAT"] = "%d.%m.%Y %H:%M"
else:
app.config["DATETIME_FORMAT"] = "%m-%d-%Y %H:%M"
content of /run.py
from app.app import app
app.run(host='localhost', port=8080, debug=True)
when i start app it throws that error "KeyError: 'DATETIME_FORMAT'". i think forms.py load before request so it throws keyError.
What is the correct way for solving this problem.
Oh, I see your problem, the date format you want is changing on a per-request basis. app.config won't help you with this.
Here's what I would do:
from flask import g
from wtforms import DateTimeField
class I18NDateTimeField(DateTimeField):
def __init__(self, label=None, validators=None, format=None, **kwargs):
if g.user.language == "tr"
format = "%d.%m.%Y %H:%M"
else:
format = "%m-%d-%Y %H:%M"
super(I18NDateTimeField, self).__init__(label=label, validators=validators, format=format, **kwargs)
class PostForm(Form):
post_date = I18NDateTimeField("Post Date", validators =[v.Required(message=_("Post date is required"))] )
Background
You're (mostly) right, before_request hasn't been called yet. That said, the form definition doesn't happen in a request context at all, it happens when the app is imported, long before any requests arrive, and it won't happen more than once.
However, the form and its fields will be instantiated again for every request, and that's why this works. It's ok to modify self.format here since this field object is only being used for this request anyway.
Update 2:
I edited my answer to subclass Form instead of BaseForm. BaseForm is part of WTForms's low-level API; they say not to use it unless you're sure you need to. I also put that internationalization logic in the constructor rather than process_formdata (thanks to mattupstate from #pocoo for the idea).
I think it's a little clearer that way, and inspecting the field in the debugger will make more sense. Now, the way the code is written, you'd expect the field to be instantiated as a class attribute when the form is defined, which means that wouldn't work and this code wouldn't be thread-safe. But due to some metaclass trickery, the field is actually instantiated as an instance attribute when the form is instantiated. Note that that metaclass trickery doesn't work properly if you use BaseForm, which is another reason to avoid BaseForm.
Update 3:
Sorry, just talked with you on IRC and found out you wrote your own BaseForm that subclasses Form. That's perfectly fine :)
I'm not sure if it would be configured correctly when you do that. Your app.config is probably not on the app because of the structure of how you made it. Did you make it like app = Flask(__name__) and import that?
You could probably solve it by using the app factory pattern
# app/__init__.py
def create_app():
app = Flask(__name__)
app.config.from_object('app.settings.default')
from app.yourforms import bp
app.register_blueprint(bp)
return app
You can make a blueprint in a separate file like so:
# yourforms/__init__.py
from flask import Blueprint
bp = Blueprint('forms', __name__)
from . import views
Then in your views.py file in that same directory, use the blueprint
from flask import current_app
from . import bp
from .forms import PostForm
#bp.before_app_request
def set_datetime_format():
# your code
# access app's config with current_app.config.get('YOURKEY')
then you just need to tweek your runfile a little bit, to do this:
if __name__ == '__main__':
app = create_app()
app.run()
Related
My project is a react project.
My website is a mutilanguage website, when I change the web language. moment.locale(lang) not working.
My code is:
const startDate = moment.utc(start).locale(lang);
const endDate = moment.utc(end).locale(lang);
whatever I set lang I check the startDate.locale() always is 'en'
startDate.format('ll') result always is English.
If the project was created using create-react-app, moment locales were probably excluded by default.
This is now documented in the "Moment.js locales are missing" section of create-react-app's troubleshooting guide.
Solution: explicitly import locales in addition to 'moment':
import moment from 'moment';
import 'moment/locale/fr';
import 'moment/locale/es';
// etc. as required
According to this github issue, from 2022 on or so, it has to be imported like so:
import moment from 'moment';
import 'moment/dist/locale/de';
moment.locale('de');
if this doesn't work, try this change:
import moment from 'moment/dist/moment';
I think if you do
import 'moment/min/locales'
Instead of individual import of each locale.
In my case it resolve my problem
I found the solution here: https://stackoverflow.com/a/55334751/8318855
You should use the moment.updateLocale function
I am trying to learn Django Cms but here is where I have stuck. IN the following code of Django CMS official documentation
Link:-http://docs.django-cms.org/en/release-3.4.x/introduction/plugins.html
from cms.plugin_base import CMSPluginBase
from cms.plugin_pool import plugin_pool
from polls_cms_integration.models import PollPluginModel
from django.utils.translation import ugettext as _
class PollPluginPublisher(CMSPluginBase):
model = PollPluginModel # model where plugin data are saved
module = _("Polls")
name = _("Poll Plugin") # name of the plugin in the interface
render_template = "polls_cms_integration/poll_plugin.html"
def render(self, context, instance, placeholder):
context.update({'instance': instance})
return context
plugin_pool.register_plugin(PollPluginPublisher) # register the plugin
I am unable to get the use of line module = _("Polls")
from django.utils.translation import ugettext as _
Django I18N documentation
In order to make a Django project translatable, you have to add a minimal number of hooks to your Python code and templates. These hooks are called translation strings. They tell Django: “This text should be translated into the end user’s language, if a translation for this text is available in that language.” It’s your responsibility to mark translatable strings; the system can only translate strings it knows about.
...
Specify a translation string by using the function ugettext(). It’s convention to import this as a shorter alias, _, to save typing.
I am using one of jMeter plugins 'JP#GC response times over time' to display results and I would like to change the look of that graph.
Is there any way to do so ? For instance changing the font in the above mentioned graph.
Thank you.
I'm afraid it's kind of relying on Java defaults which are in %JAVA_HOME%/jre/lib/fontconfig.properties.src so you'll have to either change Java defaults (it'll have global level) or patch source code of Response Times Over Time listener.
If you need once-only hack you can use Beanshell Sampler somewhere at the very beginning of your script to change font family, size, etc on-the-fly. See following example for details:
import javax.swing.*;
import javax.swing.plaf.FontUIResource;
import java.awt.*;
import java.util.Enumeration;
Enumeration keys = UIManager.getDefaults().keys();
while (keys.hasMoreElements()){
Object key = keys.nextElement();
Object value = UIManager.get(key);
if (value instanceof javax.swing.plaf.FontUIResource) {
UIManager.put(key, new FontUIResource(new Font("MS Mincho", Font.PLAIN, 50)));
}
}
I am trying to build a form package for a Plone website. I am currently working with Plone 4.3. Before I was using Dexterity with five.grok and grok libraries. But after reading the Plone 4.3 migration and five.grok dependency section of this article: http://developer.plone.org/components/grok.html it appears that Plone developers are moving away from using grok all together.
So should I move away from using Grok and how would I go about doing so when all the current documentation is currently using Grok? Additionally I am developing from a Windows based machine.
First creating form without grok is not that hard and do not depends on your Operating System.
Creating a form is always the same. Here is how I proceed:
Some imports
from Products.Five.browser import BrowserView
from plone.autoform.form import AutoExtensibleForm
from plone.app.z3cform import layout
from zope import interface
from zope import schema
from zope import component
from z3c.form import form
from collective.my.i18n import _
Create a schema
class AddFormSchema(interface.Interface):
what = schema.Choice(
title=_(u"What"),
vocabulary="plone.app.vocabularies.UserFriendlyTypes"
)
where = schema.Choice(
title=u"Where",
vocabulary="collective.my.vocabulary.groups"
)
create a generic adapter to fill the form from anywhere
class AddFormAdapter(object):
interface.implements(AddFormSchema)
component.adapts(interface.Interface)
def __init__(self, context):
self.what = None
self.where = None
Then write the form
class AddForm(AutoExtensibleForm, form.Form):
schema = AddFormSchema
form_name = 'add_content'
Add a view
class AddButton(layout.FormWrapper):
"""Add button"""
form = AddForm
Now ZCML time this is the step you don't need when using grok:
<adapter factory=".my.AddFormAdapter"/>
<browser:page
for="*"
name="my.addbutton"
class=".my.AddButton"
template="addbutton.pt"
permission="zope2.View"
/>
Should you move from grok:
This is depending of what are you doing. For an addon I say Yes but for a project, it's up to you.
Grok is not parts of the already big Zope. So adding dependency is something that always should be done only if needed. Grok is an option so I have never used it.
What's the best (or simplest) way to delete portlets site-wide in plone 4.x?
It depends. If you have a small amount of local assigned portlets I suggest the manual way. If you have a complex assignment of local portlets you could take this way:
1- create a browser view linked to the site root
2- add this:
from Products.Five import BrowserView
from Products.CMFCore.utils import getToolByName
from zope.component import getMultiAdapter
from plone.portlets.interfaces import IPortletManager
from plone.portlets.interfaces import IPortletAssignmentMapping
from plone.portlets.interfaces import ILocalPortletAssignable
class MyView(BrowserView):
def __call__(self):
ctool = getToolByName(self.context, 'portal_catalog')
all_brains = ctool.searchResults()
for i in all_brains:
obj = i.getObject()
if not ILocalPortletAssignable.providedBy(obj):
continue
for manager_name in ('plone.leftcolumn','plone.rightcolumn'):
manager = getUtility(IPortletManager, name=manager_name)
assignment_mapping = getMultiAdapter((obj, manager),
IPortletAssignmentMapping)
for i in assignment_mapping.keys():
del assignment_mapping['assignment_mapping']
Usually retrieving all objects is not a good thing, so you should evaluate carefully the amount of contents and local portlers. That said, this way is a bit aggressive but it will do the job.
I think you made a small typo:
del assignment_mapping['assignment_mapping']
should be:
del assignment_mapping[i]