1 | |
---|
2 | Blackout filtering |
---|
3 | ================== |
---|
4 | |
---|
5 | Sitemaps has option to filterout objects, which shouldn't present |
---|
6 | in a sitemap. This option is accessable in sitemap edit form |
---|
7 | and present as "Blackout entries" lines field. |
---|
8 | |
---|
9 | In earlier (<3.0.7 and <4.0.1) versions of the package the field |
---|
10 | filter-out objects only by its ids, and looks like: |
---|
11 | |
---|
12 | <pre> |
---|
13 | index.html |
---|
14 | index_html |
---|
15 | </pre> |
---|
16 | |
---|
17 | So all objects with "index.html" or "index_html" ids excluded |
---|
18 | from the sitemap. |
---|
19 | |
---|
20 | In the new versions of GoogleSitemaps filtering was remaked |
---|
21 | to pluggable architecture. Now filters are named mutli adapters. |
---|
22 | By default there are only two most useful filters - "id" and |
---|
23 | "path". |
---|
24 | |
---|
25 | Because of different filters can be used - new syntax applied |
---|
26 | to the "Blackout entries" field. Every record in the field |
---|
27 | should follow the spec: |
---|
28 | |
---|
29 | [<filter name>:]<filter arguments> |
---|
30 | |
---|
31 | By default (if no <filter name> specified) - "id" filter will |
---|
32 | be used. If <filter name> specified - system looking for |
---|
33 | <filter name> name multiadapter to IBlackoutFilter interface. |
---|
34 | If such multiadapter was not found - it's ignored silently. |
---|
35 | |
---|
36 | |
---|
37 | Setup |
---|
38 | ===== |
---|
39 | |
---|
40 | First, we must perform some setup. We use the testbrowser that is shipped |
---|
41 | with Five, as this provides proper Zope 2 integration. Most of the |
---|
42 | documentation, though, is in the underlying zope.testbrower package. |
---|
43 | |
---|
44 | >>> from Products.Five.testbrowser import Browser |
---|
45 | >>> browser = Browser() |
---|
46 | >>> portal_url = self.portal.absolute_url() |
---|
47 | |
---|
48 | The following is useful when writing and debugging testbrowser tests. It lets |
---|
49 | us see all error messages in the error_log. |
---|
50 | |
---|
51 | >>> self.portal.error_log._ignored_exceptions = () |
---|
52 | |
---|
53 | With that in place, we can go to the portal front page and log in. We will |
---|
54 | do this using the default user from PloneTestCase: |
---|
55 | |
---|
56 | >>> from Products.PloneTestCase.setup import portal_owner, default_password |
---|
57 | >>> browser.open(portal_url) |
---|
58 | |
---|
59 | We have the login portlet, so let's use that. |
---|
60 | |
---|
61 | >>> browser.open('http://nohost/plone/login_form') |
---|
62 | >>> browser.getLink('Log in').click() |
---|
63 | >>> browser.url |
---|
64 | 'http://nohost/plone/login_form' |
---|
65 | >>> browser.getControl('Login Name').value = portal_owner |
---|
66 | >>> browser.getControl('Password').value = default_password |
---|
67 | >>> browser.getControl('Log in').click() |
---|
68 | >>> "You are now logged in" in browser.contents |
---|
69 | True |
---|
70 | >>> "Login failed" in browser.contents |
---|
71 | False |
---|
72 | >>> browser.url |
---|
73 | 'http://nohost/plone/login_form' |
---|
74 | |
---|
75 | |
---|
76 | |
---|
77 | Functionality |
---|
78 | ============= |
---|
79 | |
---|
80 | First create several documents for demonstrations. |
---|
81 | |
---|
82 | In the root of the portal |
---|
83 | |
---|
84 | >>> self.addDocument(self.portal, "doc1", "Document 1 text") |
---|
85 | >>> self.addDocument(self.portal, "doc2", "Document 2 text") |
---|
86 | |
---|
87 | And in the memeber's folder |
---|
88 | |
---|
89 | >>> self.addDocument(self.folder, "doc1", "Member Document 1 text") |
---|
90 | >>> self.addDocument(self.folder, "doc2", "Member Document 2 text") |
---|
91 | |
---|
92 | We need add sitemap, of corse, for demonstration. |
---|
93 | |
---|
94 | >>> browser.open(portal_url + "/prefs_gsm_settings") |
---|
95 | >>> browser.getControl('Add Content Sitemap').click() |
---|
96 | |
---|
97 | Now we bring-up to edit form of the newly created content sitemap. |
---|
98 | We interested in two things: "Blackout entries" field must present |
---|
99 | in the form and "Save" button. |
---|
100 | |
---|
101 | >>> blackout_list = browser.getControl("Blackout entries") |
---|
102 | >>> blackout_list |
---|
103 | <Control name='blackout_list:lines' type='textarea'> |
---|
104 | >>> save_button = browser.getControl("Save") |
---|
105 | >>> save_button |
---|
106 | <SubmitControl name='form.button.save' type='submit'> |
---|
107 | >>> save_button.click() |
---|
108 | |
---|
109 | |
---|
110 | |
---|
111 | |
---|
112 | |
---|
113 | |
---|
114 | |
---|
115 | ... |
---|
116 | |
---|
117 | |
---|
118 | |
---|
119 | Return blkack-out filtered objects |
---|
120 | Every record in blackout_list filter should follow the spec: |
---|
121 | [<filter name>:]<filter arguments> |
---|
122 | For example: |
---|
123 | 1| index.html |
---|
124 | 2| id:index.html |
---|
125 | 3| path:/folder_1_level/obj_in_folder |
---|
126 | 4| path:./folder_near_sitemap/obj_in_folder |
---|
127 | 5| foo_filter:arg-1, arg-2 |
---|
128 | |
---|
129 | 1->used default "id" filter - remove "index.html" objects; |
---|
130 | 2->explicit "id" filter - remove "index.html" objects; |
---|
131 | 3->"path" filter - remove /folder_1_level/obj_in_folder object, |
---|
132 | path from the root of the plone site; |
---|
133 | 4->same to 3), but path get from the folder, where sitemap is located; |
---|
134 | 5->filter name is "foo_filter" (must be registered IBlackoutFilter, |
---|
135 | named "foo_filter"), which get filter arguments: arg-1, arg-2 |
---|
136 | |
---|
137 | class FooFilterUtility(object): |
---|
138 | def __init__(self, context, request): |
---|
139 | self.context = context |
---|
140 | self.request = request |
---|
141 | def filterOut(self, fdata, fargs): |
---|
142 | # some logic to filter-out fdata by fargs with taking into |
---|
143 | # consideration self.context and self.request, if needed. |
---|