Hello! @tidyui
I have been trying for hours, but struggling to find the answer how can I access posts/archives from a different View/Model.
I don't think it should be that difficult, but I am doing something wrong maybe. Could you please give me some directions for that?
Regards,
Chris
Hi there! For getting an archive for a period, category or tag you can access the methods in the ArchiveRepository in the Api.
You can also access posts directly by calling the PostRepository in the Api
https://github.com/PiranhaCMS/piranha.core/blob/master/core/Piranha/Repositories/IPostRepository.cs
As a last resort if you need to do advanced queries you can query the DbContext directly by injecting an Piranha.IDb into you class. If you're using cache I suggest you just select the Id of the posts and then retrieve them through the Api as posts will be cached.
var selection = db.Posts.Where(...).Select(p => p.Id);
var posts = new List<PostBase>();
foreach (var id in selection)
{
posts.Add(api.Posts.GetById<PostBase>(id);
}
Best regards
Did this answer your question so I can close this issue for now?
Hi there
Sorry for the delay. I have tried something, but it does not work, sadly. Let's imagine that we have the following situation:
I've got a page model in Project.Models called Items. This model extends ArchivePage and I have 2 types of posts in it.
I also have a View using this model, containing an iterator, getting all posts in the archive (no matter what the type is).
What I want to achieve is, to apply the same logic, but for let's say a different View, using a model ItemsNeeded in Project.Models.
Short story long:
Project.Models.Items -> View -> foreach (var post in Project.Models.Items.Archive) {do that}
Project.Models.ItemsNeeded -> View -> get the posts from the above page.
Regards,
Chris
@tidyui did I do something wrong?
Sotry for not responding. I don鈥檛 really understand what you鈥檙e trying to achieve here.
The data on the page will be accessed if you load it through the api, if your controller loads additional data then you鈥檒l have to do it manually in the second page as well!
Hi
Can you give me a general example of how would you display all posts (of two different types) on two separate.cshtml pages?
If you have View1, using ArchivePage model and View2, using a basic Page model. Is it possible to get the posts from the first page?
Sorry, but I will probably be able to give you screenshots tomorrow if I am still not clear what I try to achieve.
Chris
Hi! Let me try to explain how Posts & Pages are structured in the database.
All posts are stored in the Piranha_Posts table and can be accessed from the PostRepository in the api using api.Posts. Each post has a foreign key BlogId that specifies which Archive Page it belongs to.
Archive pages are just a special kind of page that are used for structuring posts, categories and tags. The page Id is the key that is referenced in the field BlogId on the posts.
The Archive Page model can be loaded from the ArchiveRepository and loads posts from one archive, with the possibility to filter on time period, category or tag.
var allPosts = api.Posts.GetAll<Piranha.Models.PostBase>();
This will get all Posts from all Archive Pages materialized as their different types.
var posts = api.Posts.GetAll<Piranha.Models.PostBase>(arhcivePageId);
This gets all Posts from a single Archive Page materialized as their different types.
You can also inject the current DbContext by adding an IDb parameter to your constructor. From there you can select posts on any criteria you want, for example.
var tenLatestPostsFromAllArchives = db.Posts
.Where(p => p.Published >= DateTime.Now)
.OrderByDescending(p => p.Published)
.Take(10)
.Select(p => p.Id)
.ToList();
var posts = new List<Piranha.Models.PostBase>();
foreach (var id in tenLatestPostsFromAllArchives)
{
posts.Add(api.Posts.GetById<Piranha.Models.PostBase>(id);
}
If you have full cache enabled GetById will be cached and the posts will only be fetched from the database the first time. If you can't use caching you can also do more advanced queries to actually select the data using the DbContext and transform them using the ContentService, but we can get into that if you need it :)
Regards
Hi!
Many thanks for your response. It looks like waiting for it was really worth it.
Now I have a bit more of an understanding how Archives/Posts work. Getting posts from a single page is what I needed, thanks.
The thing is, that I need all posts from 2 types in one variable, but I guess that this could be done in an array.
I think I will use the API, but I might as well try the other approach. Only thing I am not sure about is - by constructor, did you mean the page model? If so, okay. If not, is it in the controller, where you are passing api?
And yes, I have full cache enabled, but I don't really know what ContentService is for. If you are including it in the docs, there is no need to explain it now, you've done enough.
Thanks again,
Chris
Requesting posts as PostBase (which is an abstract base class) will in fact get all types.
// This gets all post types
var allPosts = api.Posts.GetAll<Piranha.Models.PostBase>();
// This gets all posts without regions & blocks
var smallPosts = api.Posts.GetAll<Piranha.Models.PostInfo>();
// This gets just a specific post type
var somePosts = api.Posts.GetAll<MyPostType>();
Regards
Hi
Thank you for the explanation, you might close the issue if you want.
Chris