ComponentLookupError when trying to create new dexterity objects - plone

I'm following a tutorial about manipulating dexterity content objects. It explains how to create objects.
from zope.component import createObject
context = createObject('example.type')
But I'm not sure what to put instead example.type. I tried using IProduct, degu.product.IProduct and degu.Product. But all of them raise a ComponentLookupError.
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/home/daniel/.buildout/eggs/zope.component-3.9.5-py2.6.egg/zope/component/_api.py", line 220, in createObject
return getUtility(IFactory, __factory_name, context)(*args, **kwargs)
File "/home/daniel/.buildout/eggs/zope.component-3.9.5-py2.6.egg/zope/component/_api.py", line 169, in getUtility
raise ComponentLookupError(interface, name)
ComponentLookupError: (<InterfaceClass zope.component.interfaces.IFactory>, 'degu.commerce.product.IProduct')

You need to use the same name that you used in the the Dexterity FTI registration.
You can verify what names are registered in the portal_types tool:
from Products.CMFCore.utils import getToolByName
typestool = getToolByName(context, 'portal_types')
print typestool.listContentTypes()
or visit the portal_types tool in the ZMI in your browser and look at the list of types there; they are listed as typeid (Type Title) in the tool. If your type isn't listed there ensure that you properly registered your type first.
Note that for this to work, you need the local component manager set up correctly. Normally, this happens automatically, but if you are using a bin/instance run script or use bin/instance debug, that doesn't happen. You need to do that manually in that case:
from zope.app.component.hooks import setSite
from Testing.makerequest import makerequest
app = makerequest(app)
site = app[site_id]
setSite(site)
You may also want to set a current user:
from AccessControl.SecurityManagement import newSecurityManager
user = app.acl_users.getUser('admin').__of__(site.acl_users)
newSecurityManager(None, user)

Related

import a dotfile into the project

I wanna import a dotile, which is on the project's root, and parse it within my middleware
something like:
import browserListDefinitions from './.browserslistrc';
but I get the TS error: TS2307: Cannot find module './.browserslistrc' or its corresponding type declarations.
I've defined the following within global.d.ts:
declare module '.browserslistrc' {}
but nothing changes. Should I install a raw loader and set it properly?

what does this line indicate:- module = _("Polls") in Django CMS PollPluginPublisher

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.

Reimport updated module to python

I have the following scenario in python3
from phase_2d import phase_2d #where phase_2d is a python file phase_2d.py
I then edit this file and want to test the changes, without having to quit python and reload everything.
imp.reload(phase_2d)
returns the error 'Type:Error: reload() argument must be module'
Since you imported the phase_2d class from the module phase_2d, when you call imp.reload(phase_2d), the phase_2d being passed to the reload command is the class, not the module. In order to use the reload command, you must import the actual module, or otherwise get a reference to the module. For example, you could do something like this:
import phase_2d
from phase_2d import phase_2d as p2d
...
imp.reload(phase_2d)
Or, if you really only want to import the single class from the module, you could use the inspect module to get the parent module from the class (http://docs.python.org/2/library/inspect.html#inspect.getmodule)
import inspect
from phase_2d import phase_2d
....
imp.reload(inspect.getmodule(phase_2d))

Creating Events with Plone Form Gen

I am trying to create an Event content type using Plone Form Gen. I have been using this tutorial in order to do this.
When creating an Event content type using the Add New... menu, you are given two fields to fill in that are start and end dates for the event, I would like my form to pull the information from these fields and apply it to the event content type I am using to create it.
My problem as I understand it is described with examples below:
The custom script adapter script contains the following:
obj.setDescription(form['replyto'])
I can see that it gets the contents for the Description of the Event content type from the following:
<input id="replyto" class="" type="text" size="30" name="replyto" />
The date/Time field when added to a PFG form, is made up of multiple <select> inputs and not just one like the above, I guess this means there isn't a simple obj.setEndDate() command for this... Although with no way to reference the select boxes I'm kind of stuck.
Does anyone know if it is possible to create an Event content type and specify start and end dates on it, using Plone Form Gen?
Edit
Using this link I have gotten around the original issue but I have run into more problems
I have adapted my script (using the above link) to look like the following:
target = context.viewjobs
form = request.form
from DateTime import DateTime
uid = str(DateTime().millis())
loc = form['location-of-event']
target.invokeFactory("Event", id=uid, title=form['topic'], event_url=loc)
obj = target[uid]
obj.setFormat('text/plain')
obj.setText(form['comments'])
obj.setDescription(form['replyto'])
obj.reindexObject()
(I used event_url just to test as I wasn't having any luck with the event_start option).
It creates the event alright, but when I go to view the event I get:
Module zope.tales.expressions, line 217, in __call__
Module Products.PageTemplates.Expressions, line 147, in _eval
Module zope.tales.expressions, line 124, in _eval
Module Products.PageTemplates.Expressions, line 74, in boboAwareZopeTraverse
Module OFS.Traversable, line 317, in restrictedTraverse
Module OFS.Traversable, line 285, in unrestrictedTraverse
__traceback_info__: ([], 'location')
AttributeError: location
I have not referenced location anywhere in my script, and when I do, I get the same error.
Any thoughts would be appreciated
You can simplify your code and avoid the reindex call by doing something like this:
target = context.viewjobs
form = request.form
from DateTime import DateTime
uid = str(DateTime().millis())
target.invokeFactory(
"Event",
id=uid,
title=form['job-title'],
description=form['description-1'],
text=form['comments'],
location=form['location-of-event'],
startDate=form['start-date'],
endDate=form['end-date-due-by']
)
With regard to collecting the starting and ending date. If you use the Date/Time widget and look at the HTML that is generated you will notice there is a hidden input field who's name matches the short-name of the widget. That hidden input contains a full textual representation of what was selected by the various select boxes, thus giving you want you achieved by using a text field but without having to rely on the user to use a specific format.
If you're wondering how to find the names of the various fields to specify in the invokeFactory call, find the python file that defines the content type your trying to create. In the case of the event object it's /Plone/buildout-cache/eggs/Products.ATContentTypes-2.1.8-py2.7.egg/Products/ATContentTypes/content/event.py
Line 32 starts "ATEventSchema = ..." and from there you will see the field names for all the parts of an event.
I managed to resolve this by using a text field and asking the users to enter the date in this format: 2013-12-12, I then used obj.setStartDate(form['name-of-field']) and obj.setEndDate(form['name-of-field']) to set that on the Event.
To get around the Location traceback, I used obj.setLocation() and removed the location line from the invoke method shown in the script above.
Script for anyone who's interested:
target = context.viewjobs
form = request.form
from DateTime import DateTime
uid = str(DateTime().millis())
target.invokeFactory("Event", id=uid, title=form['job-title'])
obj = target[uid]
obj.setFormat('text/plain')
obj.setText(form['comments'])
obj.setDescription(form['description-1'])
obj.setLocation(form['location-of-event'])
obj.setStartDate(form['start-date'])
obj.setEndDate(form['end-date-due-by'])
obj.reindexObject()

Delete all portlets site-wide in Plone

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]

Resources