Get page URL for scheduled publishing - wagtail

My editors want to know the end page url for publishing in social media.
Is there any way to get the page URL as when it will be published before actually publishing it (scheduled publishing)?

slug_url should give you what you need:
https://docs.wagtail.org/en/latest/topics/writing_templates.html?highlight=slugurl#slugurl-tag
Note that slugurl might provide a relative link, so if it does, then you would have to prepend the domain name to the relative url in order to create the final url for the user. See the test_slugurl_tag() routine in the tests for an example of how to use slugurl in Python code.
Note also that if the location of the page in the page tree is changed or the slug (as defined in the Promote tab) is changed, then the url that you retrieved with slugurl prior to any such change will no longer be valid. However, if you are using Wagtail 2.16+, then this problem can be handled automatically if you use the wagtail.contrib.redirects app.

Here a code snippet that takes in account when the slug changes or the page is moved in the tree (you will need to subclass the Page model somehow and add a new field published_url):
def save_revision(self, user=None, submitted_for_moderation=False, approved_go_live_at=None, changed=True,
log_action=False, previous_revision=None, clean=True):
old_record = Page.objects.get(id=self.id)
if old_record.slug != self.slug:
kwargs = {'update_fields': ['slug']}
Page.save(self, kwargs)
self.published_url = self.get_full_url()
return Page.save_revision(self, user, submitted_for_moderation, approved_go_live_at, changed,
log_action, previous_revision, clean)

Related

How to disable index searching on the list and just get the articles indexed on search results?

Using 2sxc Blogg App and when using search I get the results of the blog home page listed, which simply list the blog home and the article titles which all take the user to the blog home page, so they are pretty much useless links, then I get the actual articles with the links to the articles. So I need to suppress the blog page itself, but not its dynamic children (the articles).
/help <-- no, thanks, your links are useless.
/help/post <-- yes, please, list all.
Any idea on how I could achieve that? I got directed to CustomizeData() doc, but I have no idea what to do. The current one set on the main blog list page is as follows:
#functions{
/// <summary>
/// Populate the search - ensure that each entity has an own url/page
/// </summary>
/// <param name="searchInfos"></param>
/// <param name="moduleInfo"></param>
/// <param name="startDate"></param>
public override void CustomizeSearch(Dictionary<string, List<ToSic.SexyContent.Search.ISearchInfo>> searchInfos, DotNetNuke.Entities.Modules.ModuleInfo moduleInfo, DateTime startDate)
{
foreach (var si in searchInfos["SearchIndex"])
{
si.QueryString = "post=" + AsDynamic(si.Entity).UrlKey;
}
}
}
welcome to StackOverflow ;)
The basic DNN index asks each module for the data it has, and then builds the index on that. Since a module can have multiple items for the search, they are each an own "document" which can be configured - for example what URL to use in the search results. To enable view-developers to customize these things, 2sxc has this hook to customize the search results. So the way it's meant to work is...
the backend collects the data
then detects that the search index is being built (and not a user viewing the page)
then call the code for optional reconfiguration
then pass the items on to DNN search
So what the code should do is take each item as it was prepared by the backend, change the url to use and then let the rest of the system do its magic. If this isn't working, there are a few possibilities:
something in DNN or 2sxc is broken (I really hope that's not it)
the code caused errors and since it happens in the background, you don't see it
the data is not being passed to the code, for example because it was filtered out - for example, old data isn't updated in the index, because the indexer will ask for new data only, and therefor older data won't be updated on normal re-indexes, no matter how you update the code.
Let's try to find out what the cause is
open the app query https://azing.org/2sxc/r/T1GdqnNa and select the **Blog Posts for Home and Tags", and test-run the query to see if it gives you results. if not, something may be wrong with the query. In the json-looking test-results on the screen, do check if there is something in the set "SearchIndex" - this is the data stream that skips paging and returns all items. If this is empty, get back to us. Note: if you don't get any results, do check what Test-Parameters the query is using (box to the right), and maybe edit the ModuleId in case it's wrong
check if you see any events in the DNN event-log. if you don't, make sure you re-index the whole data in DNN and check again.
Post your results, so we can check how this can be fixed ;)

wagtail modeladmin: is it possible to add "explore child pages" column?

I've been using wagtail-modeladmin to create custom lists of certain page types. That gives me the ability to edit those pages. But I'd also like to be able to click through somehow to the "normal" admin explorer version of those pages, and be able to view/add child pages to them.
essentially giving myself a column with the little arrows in on the right, just like in the normal wagtail admin page explorer...
OK I know it's bad form to answer your own question, but I've got this working by using a custom method on the model admin object that reverse wagtails admin urls:
class MySpecialPageModelAdmin(ModelAdmin):
def view_children(self, obj):
url = reverse('wagtailadmin_explore', args=[obj.id])
return format_html(f'View Children')
list_display = ('title', 'live', 'view_children')
but actually, I think I'm not going to end up using this, just replacing this particular modeladmin with a direct link to the right place in the explorer.

Is it possible to generate temporary URL or route using angular and ui-router?

As the question title says, is it possible to generate a temporary URL using ui-router that routes to a view which displays data of a patient without showing patient ids or any identifying information in the URL? The link should be generated when a button is clicked. In other words, a url with random characters like www.example.com/xuye9039j23l. Once this URL is viewed and processed (say save button is clicked, then the URL can't be used again). Can someone give me a logic on how this can be made possible? I guess it would be somewhat similar to password recovery email in which the link expires once it's clicked. I'm using C# Web API if it is important.
I believe this might be the answer you are looking for: Angular ui router passing data between states without URL
However, I would consider a different strategy if you would like more granularity in control of the accessibility of this report.
Assuming you have a database to work with, perhaps you could create a new database table which might contain the following:
The ID of the user
A temporary generated token which will be used for routing to your patient details page
Perhaps a expiration date/time.
have your button call an API endpoint on your web server which might do the following:
Given a users ID and some subset of information, generate a hash of the information (include the ID of the current column as this will ensure uniqueness of the hash for multiple links generated for the same user). This will be the token.
Store the hash in your new database table with an expiration date/time.
Respond to the web request with the hash/token so you can route to the client details page with the token.
Then, when the user is redirected to the client details page, you can use your back-end (web server) to check for expiration or any other limiting factors you wish to put in place for the accessibility of this page.
Just my thoughts on the matter.
Yes this is possible. It has more to do with your backend code then javascript.
In essence you will need to have a server validate your id, and if it is valid display message. If it is not valid return 400 or something and tell them they have an invalid id. You will need to persist the Id to a datastore with some sort of time/use column saying if it is valid or not.
I will give a WebAPI example.
app.controller('myCtrl', function($scope,$stateParams,patientService) {
if($stateParams.id != undefined)
{
patientService.Get($stateParams.id).then(function(success){
$scope.Data = success;
},
function(error)
{
//redirect or display cannot use this url message
}
});
}
WebAPI
public HttpResponseMessage Get(string id)
{
//use business logic to validate ID
//if Id is valid return cool data
if (isValid(id))
{
return request.CreateResponse(HttpStatusCode.OK,data);
}
return request.CreateResponse(HttpStatusCode.BadRequest);
}

How to process and change output before it is sent back to the browser?

I want to implement a mechanism in CakePHP that is like ShortCodes in Wordpress. I want to save my pages (in the DB) with tokens, e.g.
[form id=12]
and then, after the view got rendered and before it is sent back to the browser, I want to search the rendered view for these tokens, and replace them with something else.
I assume I'll have to use beforeFilter, afterFilter or beforeRender, but I can't find any documentation (including in CakePHP's own documentation!) about how these overriden functions can be used to change the output.
Can anyone help?

Nested CakePHP Routing

I'm working on a CMS and would like to configure cake to automatically find the proper page to use based upon the URL. I don't want to have to manually set this and want it to automatically work if I create new pages (based upon slugs).
Let's say I have the following "page layout":
News
-Local
-World
-article1
Products
-Product1
-details
-photos
etc
So: mysite.com/local/world/article1 would load "Article1". If I added a page under article1 titled "photos", then: mysite.com/local/world/article1/photos would work. Also, mysite.com/products/product1/details would work, etc. Any page I add to the site should be available (it should use a parent/child method). Any tips on making this happen with CakePHP?

Resources