It's tough to find good documentation on this. I am trying to build a simple search engine for a very small Django CMS site built with CMS version 2.4. I have found out the best way is with Haystack + django-cms-search, which then tells me that package is deprecated and to use aldryn-search instead, the documentation is lacking big time.
From what I can gather, I need to create a search_indexes.py but where does this go? I thought this was app specific? If I am just using it to index Page model from the CMS, how do I go about integrating that?
For cms versions < 3.0 then django-cms-search would be your solution, once you switch to >= 3.x then aldryn-search is the way to go.
The reason for this is that aldryn-search is basically a fork/refactor of django-cms-search targeting haystack 2.x and cms 3.x
I'm considering adding backwards compatibility for aldryn-search to work on cms 2.4 but to get you up and running, here's what you can do.
Install django-cms-search and add haystack and cms_search to your INSTALLED_APPS setting.
This should allow you to start indexing pages already, if not please post a traceback :).
Once you are able to index pages, now it's up to you if you want to manage the search page through the cms using an apphook or a fixed url.
Usually when working with search, one needs to tweak some things and add search specific templates, for this I highly recommend creating a search app in your project, add a models.py and then add this app to your INSTALLED_APPS.
Now back to the search page, if you choose to use an apphook, then in your search app, create a cms_app.py file and add the following:
from cms_search.cms_app import HaystackSearchApphook
apphook_pool.register(HaystackSearchApphook)
this registers the packaged apphook from django-cms-search with the cms (this used to happen by default, but not anymore).
Otherwise, if you chose to have a fixed url not managed by the cms, you can simply add a urls.py in your search app with the following:
from django.conf.urls import *
from haystack.views import search_view_factory
urlpatterns = patterns('search.views',
url('^$', search_view_factory(), name='haystack-search'),
)
then in your project's urls.py you can include the search.urls under any name you want, like so:
url(r'^search/', include('search.urls')),
Related
So, I have inherited a Laravel 8 project from the previous developer who decided to leave for a greener pasture. And I see all this blade components everywhere, (x-this, x-that) and I have also created a few. I have used make:component command and I can see the components being generated both in `App/Views/' and 'resources/views'. That's great.
Now, there are other components, which the previous developer have created that I can't figure out where where these components are being registered at. They are not in the App directory, not in the service provider boot, there's no custom vendor in the composer.
So, I think the obvious question is, where else should I look for?
Those may be anonymous components. Anonymous components does not require any registration. So check resources/views/components folder.
For more info:
https://laravel.com/docs/8.x/blade#anonymous-components
I have an Alfresco module that I would like to have do some cleanup when a new version of it is installed.
In the current situation, an older version of the module created a folder node with custom properties at the root of the repository. We've since decided to have multiple such nodes, and none of them at that location. I'd like to put into the next version of the module code that would run at Alfresco startup, check for the existence of the old node, copy its properties into the appropriate new nodes, and delete the old node.
Is such a thing possible? I've looked at the Bootstrap configuration file, but that appears to only allow one to add things to the repository, not modify or delete them.
My suggestion is that you write a patch. That is a class that implements
org.alfresco.repo.admin.patch.AbstractPatch
Then you can do pretty much anything you want on bootstrap (except executing searches against solr since it wont be available).
Add some spring configuration, take a look at the file patch-services-context.xml for inspiration.
Yes you can do that, probably you missed the correct place in the documentation about that:
If you open Import Strategy you'll find a section Per BootstrapView, you should be using something like REPLACE_EXISTING or UPDATE_EXISTING for your ACP packaged content (if you're using ACPs as your bootstrap importing strategy).
Here is a more detailed description of the UUID Bindings values.
Hope that helps.
You can use patches.
When alfresco server starts it applies patches and executes database updates etc.
Definition :
A patch is a piece of Java code that executes once when Alfresco
Content Services starts. Custom patches can be implemented.
Documentation Link
I am trying to build a control panel following a tutorial on the Plone Documentation site.
http://docs.plone.org/develop/plone/functionality/controlpanel.html
However, I started off creating the product with (from the src folder) ../bin/zopeskel plone my.product, instead of creating with the dexterity option. I did select the easy option when it asked what mode I wanted and I did select yes when it asked if I wanted to create a GS Profile.
I made sure to include grok in configure.zcml
<include package="five.grok" />
After following the instructions, I try to run the quickinstall to install the product, but it gives me the error:
ImportError: No module named directives
referring to the line in the settings.py file of their tutorial
from plone.directives import form
I added plone.app.registry to the install_requires bit in the setup.py file, and I made sure to make the changes in the configure.zcml file to include
Just for experimenting, I did add 'plone.app.dexterity' to the install_requires, but I still got the same error.
Is grok conflicting with plone.directives? If so, how can I fix this or do I have to use deterity instead of plone as the option for creating products?
If grok is not conflicting, what could the problem be?
On a side note, the tutorial does appear to be for using dexterity to create the product, but I am not sure if that is what the problem is.
I created a gist with a howto that I wrote for plone.org some time ago:
https://gist.github.com/tisto/4ef1f6c7b445faf6ad73
This is considered best practice these days. Using grok is not recommended any longer.
As I understand it Qt provides 2 main plugin mechanisms:
Plugins that extend Qt "Qt Extensions"
Plugins that extend applications developed with Qt
I'm interested in developing plugins for my application (2).
I use PySide but can't find any resources about developing application plugins using PySide/PyQt.
Following the C++ Qt documentation I understand that the application has to use the Q_DECLARE_INTERFACE() macro and the plugins have to use both Q_INTERFACES() and Q_EXPORT_PLUGIN2() macros but I don't know the code they represent to try and translate it to python. Or is there another way I've missed?
Update:
The closest thing to a solution I could find so far is Alex Martelli's answer to a similar question. Although it looks like it would work I'd rather use an official Qt approach to avoid any cross-platform issues.
I think Qt's plugin system is intended to allow people to write C++ plugins compiled as binaries. I don't even know if it's theoretically possible to write plugins in Python that will use a C++ binary interface like that.
If you want to support Python plugins your best bet would be to use one of the many pure python plugin systems out there. I have written a PySide app that uses YAPSY to load plugin scripts. YAPSY is a very simple, compact plugin module. It's very easy to include directly in your app as it's a single file, and is BSD licensed so you can use it commercially. Just search for it on Google. I was even able to package my app using py2exe and still retain the ability to import python source file plugins from a plugin directory.
I'm a fan of the Roll Your Own approach.
By a plugin, I mean:
Plugin: a module or package loaded during runtime which augments or modifies the main module's behavior
I see two requirements for a plugin:
Can the main module load the plugin during runtime?
Is data accessible between the main module and the plugin?
Assumptions
Developing a plugin system is highly subjective. There are many design decisions to make and there is no One True Way. The usual constraints are time, effort, and experience. Be aware that assumptions must be made and that the implementation often defines terminology (e.g. "plugin" or "package"). Be kind and document those as best as possible.
This plugin implementation assumes:
A plugin is either a Python file or a directory (i.e. "plugin package")
A plugin package is a directory with structure:
plugin_package/
plugin_package.py <-- entry point
other_module.py <-+
some_subdir/ |- other files
icon.png <-+
Note that a Plugin package isn't necessarily a Python package. Whether or not a plugin package is a Python package depends on how you want to handle imports.
The plugin name is the same as the plugin entry point's file name, as well as the plugin package directory
The QApplication's QMainWindow is the primary source of data to share from the main module
1. Loading a plugin module
Two pieces of information are required to load a plugin module: the path to the entry point and the plugin's name. How these are obtained can vary and getting them usually requires string/path parsing. For what follows, assume:
plugin_path is the absolute path of the plugin entry point and,
plugin_name is the plugin name (which is the module name by the above assumptions).
Python has implemented and re-implemented the import mechanism numerous times. The import method used at the time of writing (using Python 3.8) is:
import importlib
from importlib.util import spec_from_loader, module_from_spec
from importlib.machinery import SourceFileLoader
loader = SourceFileLoader(plugin_name, plugin_path)
spec = spec_from_loader(plugin_name, loader)
plugin_module = module_from_spec(spec)
spec.loader.exec_module(plugin_module)
# Required for reloading a module
sys.modules[plugin_name] = plugin_module
# # This is how to reload a module
# importlib.reload(plugin_module)
It's probably a good idea to include error handling and a record of which modules have been loaded (e.g. by storing them in a dict). Those details are excluded here for brevity.
2. Sharing data
There are two directions which data may be shared:
Can the main module access the plugin module's data?
Can the plugin module access the main module's data?
The main module can access plugin data for free after import (by definition). Simply access the plugin module's __dict__:
# Accessing plugin data from the main module
some_data = plugin_module.__dict__.get('data')
Accessing the main module's data from within the plugin is a trickier problem.
As stated above, I usually consider the QMainWindow as synonymous with the end-user's notion of "the application". It's the primary widget users interact with and, as such, typically houses most of the data or has easy access to it. The challenge is sharing the QMainWindow instance.
The solution to sharing QMainWindow instance data is to make it a singleton. This forces any QMainWindow to be the main window users interact with. There are several ways to create singletons in Python. The two most common ways are probably using metaclasses or modules. I've had the most success using the module singleton approach.
Break the QMainWindow code into a separate Python module. At the module level, create but don't initialize a QMainWindow. Create a module-level instance so that other modules can access the instance as a module attribute. Don't initialize it because init requires a QApplication (and because the main window module is not the application entry point).
# main_window.py
from PySide2 import QtWidgets
class MyMainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
main_window_instance = MyMainWindow.__new__(MyMainWindow)
Use a separate module, such as main.py, for the application entry point. Import the main window instance, create the QApplication, and initialize the main window.
# main.py
import sys
# Importing the instance makes it a module singleton
from main_window import main_window_instance
from PySide2 import QtWidgets
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
main_window_instance.__init__()
main_window_instance.show()
sys.exit(app.exec_())
Importing the main window instance is what makes it a singleton. Creating the QApplication here isn't strictly necessary (it's a singleton, too), but feels cleaner to me.
Now, when plugins are loaded during runtime, they can import the main_window_instance. Because the main_window module has already been loaded by the main.py entry point, it's the main window used by the main module (and not a new instance). Data from the main module can now be accessed from the plugin module.
# plugin.py
# The plugin can now access the main module's data
from main_window import main_window_instance
main_window_instance.setWindowTitle('Changed from plugin')
Comments
The minimum setup requires three files: main.py, main_window.py, and plugin.py. The main_window.py defines and instantiates the main window, the main.py makes it a singleton and initializes it, and the plugin.py imports and uses the instance.
Lots of details were left out in hopes that the primary components could be made apparent. Ideally, the Qt and Python documentation should be enough to fill in the gaps...
There are further considerations, such as how to distribute and manage plugins. Plugins could be hosted remotely, packaged as (zip) archives, bundled as proper Python packages, etc. Plugins can be as simple (or as complex) as you want. Hopefully this answer provides ample inspiration for how you want your plugin system to look.
I need to develop a whole section of a website (around 10 different pages) as a DotNetNuke module. The site will be using DNN as the CMS, where editors will manage HTML content for most of the website (exception that section I'll be developing).
I've already made a rather extensive research on DNN Module Development (even watched some recorded Webinars by DNN Corp). Unfortunately, most of what I could find online is about developing simple, widget-like modules. Also, most of it uses a step-by-step "how to use visual studio to acomplish x" approach, while I was trying to understand how DNN works. So it seems I have to figure it out for myself...
At this point I'm already somewhat familiar with DNN, and I see several different solutions to my problem:
Creating a module for every page on my custom section. I don't like this idea very much, specially because I have code that need to be shared across multiple pages.
Developing a single module with several User Controls inside (one for each page), and use custom module settings to let each page know which control to display.
Develop a "bogus" module that will work as a library, and additional modules for each page.
Develop the library module, then use the Razor Host Module and Razor scripts for the views (I don't need/want WebForms on my app).
So I decided to ask you guys for advice. Which is the the preferred way to go? Maybe none of the above? I know all four options above should give me the result I want, but I also don't want to go against the "DNN way" too much...
I wouldn't recommend #1 (multiple modules) or #3 (also multiple modules) at all, and though #2 (single module w/ module level setting that determines view) is definitely a solid option used widely by DNN module developers, it sounds like you'd prefer #4 (Razor) over #2 because you like the development style.
So - I'd recommend going with the Razor approach, which though it seems like you understand the approach just fine, I wanted to elaborate on for posterity:
Build a library (assembly/DLL) to encapsulate all of your reusable business logic
Build out Razor views for each page that make use of that logic and render your data on the page
Drop the Razor Host module on each page that you need it and point it to the correct view
That should work out quite well.
I'm assuming you're looking at developing your software in the "Web Site Project" style. I'll like to recommend that you look at the "Web Application Project" style of doing things.
If you have shared functionality in a library, feel free to build an assembly and drop it in the bin folder, from there, it will be picked up by DNN and it will run in the http context, which is great!
Build your module in one project and package the different modules in your DNN manifest.
Hope i'm not talking about what you understand.
Added another answer, it's a post in itself.
Modules - That's a term that's very loosely used by all of us.
Clearer Definitions
Package = Zip file (Not Module)
Manifest = .DNN file
The manifest allows you to define Modules(group of View/Edit/Settings) user controls as a single installation package.
In the DNN 3.0 manifest, if you're still in this format, you'll notice that a basic single installation package is structured like this (briefly)
<dotnetnuke version="3.0" type="Module">
<folders>
<folder>
<name>Side bar Navigation</name>
<modules>
<module>
<friendlyname></friendlyname>
<cachetime>0</cachetime>
<controls>
<control>
<title>View</title>
<src>DesktopModules/Module/View.ascx</src>
<type>View</type>
</control>
<control>
<key>Settings</key>
<title>Settings</title>
<src>DesktopModules/Module/Settings.ascx</src>
<type>Edit</type>
</control>
</controls>
</module>
</modules>
<files>
...
</files>
</folder>
</folders>
</dotnetnuke>
So that above defines a Single Module in an Installation Package.
In the context of a blog, you would have 2 modules
Blog Display Module (displays a selected blog or just the whole lot)
Sidebar Navigation Module (Helps you
to display quickly the blogs you've
written for an any period of time)
What you can do is to package the Blog Display Module in the manifest in a copy of <folder></folder> and then the Sidebar Navigation Module in another copy of the <folder></folder> structure.
For example, this project has 7 modules; Side bar navigation, custom search module, blah blah blah
<dotnetnuke version="3.0" type="Module">
<folders>
<folder>...</folder>
<folder>...</folder>
<folder>...</folder>
<folder>...</folder>
<folder>...</folder>
<folder>...</folder>
<folder>...</folder>
</folders>
</dotnetnuke>
1 Installation Package (Which means 1 Web App Project)
7 Modules
One assembly to place in the bin/
All code is shared and you can then inherit from other library references to develop further.
They have different views, names, friendlynames but all share one common <foldername>
The KEY is in the Packaging.
<folder>
<name>BlogDisplay</name>
<friendlyname>Blog Display</friendlyname>
<foldername>WebLog</foldername>
<modulename></modulename>'
'<folder>
<name>BlogSidebar</name>
<friendlyname>Sidebar Navigator</friendlyname>
<foldername>WebLog</foldername>
<modulename></modulename>
It'll look something like this! that's where foldername is. It defines where in DesktopModules your module will be installed to.
In DNN 5 books, the Web Site Project method of development is still in use but when you're participating in development on the Core Modules, you'll find that the projects are in Web App Project development style, which is better, because all your code-behind is in an assembly and not exposed as source code on the web.
You're definitely on the right path.