def customize_cms_post(**attr): """ Customize cms_post controller """ s3 = current.response.s3 s3db = current.s3db table = s3db.cms_post field = table.series_id field.label = T("Type") field.readable = field.writable = True #field.requires = field.requires.other #field = table.name #field.readable = field.writable = False #field = table.title #field.readable = field.writable = False field = table.avatar field.default = True #field.readable = field.writable = False field = table.replies field.default = False #field.readable = field.writable = False field = table.location_id field.represent = location_represent field.requires = IS_NULL_OR(IS_LOCATION(level="L4")) field.widget = S3LocationAutocompleteWidget(level="L4") table.created_by.represent = s3_auth_user_represent_name field = table.body field.label = T("Text") field.widget = None #table.comments.readable = table.comments.writable = False crud_form = S3SQLCustomForm( "series_id", "body", "location_id", S3SQLInlineComponent( "document", name="file", label=T("Files"), fields=[ "file", #"comments", ], ), ) # Return to List view after create/update/delete url_next = URL(c="default", f="index", args=None) list_fields = [ "series_id", "location_id", "created_on", "body", "created_by", "created_by$organisation_id", "document.file", "comments", # Needed for YouTube URLs ] s3db.configure( "cms_post", create_next=url_next, delete_next=url_next, update_next=url_next, crud_form=crud_form, list_fields=list_fields, ) crud_settings = s3.crud crud_settings.formstyle = "bootstrap" crud_settings.submit_button = T("Save changes") # Done already within Bootstrap formstyle (& anyway fails with this formstyle) #crud_settings.submit_style = "btn btn-primary" # Custom PostP standard_postp = s3.postp def custom_postp(r, output): if r.representation == "plain" and \ r.method != "search": # Map Popups - styled like dataList auth = current.auth db = current.db record = r.record record_id = record.id item_class = "thumbnail" item_id = "popup-%s" % record_id table = s3db.cms_post series = table.series_id.represent(record.series_id) date = S3DateTime.date_represent(record.created_on, utc=True) body = record.body location_id = record.location_id location = table.location_id.represent(location_id) location_url = URL(c="gis", f="location", args=[location_id]) # Attachment(s)? table = s3db.doc_document row = db(table.doc_id == record.doc_id).select( table.file, limitby=(0, 1)).first() if row: doc_url = URL(c="default", f="download", args=[row.file]) doc_link = A(I(_class="icon icon-paper-clip fright"), _href=doc_url) else: doc_link = "" if series not in ("News", "Twitter", "Ushahidi", "YouTube"): # We expect an Author author_id = record.created_by author = table.created_by.represent(author_id) utable = auth.settings.table_user user = db(utable.id == author_id).select( utable.organisation_id, limitby=(0, 1)).first() organisation_id = user.organisation_id organisation = s3db.org_organisation_id.attr["represent"]( organisation_id) org_url = URL(c="org", f="organisation", args=[organisation_id]) # @ToDo: Optimise by not doing DB lookups (especially duplicate) within render, but doing these in the bulk query avatar = s3_avatar_represent( author_id, _class="media-object", _style="width:50px;padding:5px;padding-top:0px;") ltable = s3db.pr_person_user ptable = db.pr_person query = (ltable.user_id == author_id) & \ (ltable.pe_id == ptable.pe_id) row = db(query).select(ptable.id, limitby=(0, 1)).first() if row: person_url = URL(c="hrm", f="person", args=[row.id]) else: person_url = "#" author = A( author, _href=person_url, ) avatar = A( avatar, _href=person_url, _class="pull-left", ) card_person = DIV( author, " - ", A( organisation, _href=org_url, _class="card-organisation", ), doc_link, _class="card-person", ) else: # No Author card_person = DIV( doc_link, _class="card-person", ) avatar = None if series == "News": icon = URL(c="static", f="img", args=["markers", "gis_marker.image.News.png"]) elif series == "Twitter": icon = URL(c="static", f="img", args=["social", "twitter.png"]) elif series == "Ushahidi": icon = URL( c="static", f="img", args=["markers", "gis_marker.image.Ushahidi.png"]) elif series == "YouTube": #icon = URL(c="static", f="img", args=["social", "YouTube.png"]) avatar = DIV(IFRAME(_width=320, _height=180, _src=record.comments, _frameborder=0), _class="pull-left") if not avatar: avatar = DIV(IMG( _src=icon, _class="media-object", _style="width:50px;padding:5px;padding-top:0px;", ), _class="pull-left") # Edit Bar permit = auth.s3_has_permission if permit("update", table, record_id=record_id): edit_btn = A( I(" ", _class="icon icon-edit"), _href=URL(c="cms", f="post", args=[record_id, "update"]), ) else: edit_btn = "" # delete_btn looks too much like popup close! #if permit("delete", table, record_id=record_id): # delete_btn = A(I(" ", _class="icon icon-remove-sign"), # _href=URL(c="cms", f="post", # args=[record_id, "delete"]), # ) #else: delete_btn = "" edit_bar = DIV( edit_btn, delete_btn, _class="edit-bar fright", ) # Overall layout output = DIV( DIV( I( SPAN( " %s" % T(series), _class="card-title", ), _class="icon icon-%s" % series.lower(), ), SPAN( A( location, _href=location_url, ), _class="location-title", ), SPAN( date, _class="date-title", ), edit_bar, _class="card-header", ), DIV( avatar, DIV( DIV( body, card_person, _class="media", ), _class="media-body", ), _class="media", ), _class=item_class, _id=item_id, ) elif callable(standard_postp): # Call standard postp output = standard_postp(r, output) return output s3.postp = custom_postp return attr
def custom_prep(r): if r.interactive: s3db = current.s3db table = s3db.cms_post field = table.series_id field.label = T("Type") field.readable = field.writable = True #field.requires = field.requires.other #field = table.name #field.readable = field.writable = False #field = table.title #field.readable = field.writable = False field = table.avatar field.default = True #field.readable = field.writable = False field = table.replies field.default = False #field.readable = field.writable = False field = table.location_id field.represent = location_represent field.requires = IS_NULL_OR(IS_LOCATION(level="L3")) field.widget = S3LocationAutocompleteWidget(level="L3") #field.requires = IS_NULL_OR(IS_LOCATION()) #field.widget = S3LocationSelectorWidget2() table.created_by.represent = s3_auth_user_represent_name field = table.body field.label = T("Text") field.widget = None #table.comments.readable = table.comments.writable = False # Filter from a Profile page?" event_id = current.request.get_vars.get("(event)", None) if event_id: crud_form = S3SQLCustomForm( "series_id", "body", "location_id", S3SQLInlineComponent( "document", name="file", label=T("Files"), fields=[ "file", #"comments", ], ), ) def create_onaccept(form): table = current.s3db.event_event_post table.insert(event_id=event_id, post_id=form.vars.id) s3db.configure( "cms_post", create_onaccept=create_onaccept, ) else: crud_form = S3SQLCustomForm( "series_id", "body", "location_id", S3SQLInlineComponent( "event_post", label=T("Disaster(s)"), fields=["event_id"], orderby="event_id$name", ), S3SQLInlineComponent( "document", name="file", label=T("Files"), fields=[ "file", #"comments", ], ), ) # Return to List view after create/update/delete url_next = URL(c="default", f="index", args=None) list_fields = [ "series_id", "location_id", "created_on", "body", "created_by", "created_by$organisation_id", "document.file", "event_post.event_id", ] s3db.configure( "cms_post", create_next=url_next, delete_next=url_next, update_next=url_next, crud_form=crud_form, list_fields=list_fields, ) crud_settings = current.response.s3.crud crud_settings.formstyle = "bootstrap" crud_settings.submit_button = T("Save changes") # Done already within Bootstrap formstyle (& anyway fails with this formstyle) #crud_settings.submit_style = "btn btn-primary" # Call standard prep # (Done afterwards to ensure type field gets hidden) if callable(standard_prep): result = standard_prep(r) if not result: return False return True