Im building a micro CMS. Using Mysql as RDMS, and Doctrine ORM for mapping.
I would like to have two types of pages. Static Page, and Blog Page.
Static page would have page_url, and page_content stored in database.
Blog page would have page_url, but no page_content. Blog would have Posts, Categories...
Lets say I have route like this:
/{pageurl}
This is page, with page url that can be home, or news, or blog...
That page can be either Static page, and then I would joust print page_content.
But it can also be Blog Page, and then I would print latest posts as content.
How should I relate these Static Page and Blog Page tables?
Is this inheritance, since both are pages, with their URL, but they have different content?
Should I use inheritance, so that both Static and Blog page extends Page that would have page_url? Or should I made another table page_types and there store information about available page types?
Generally, and I'm speaking with a MVC framework in mind, when you use routes you would have a specific pattern that you can match to different controllers/actions that could then map to different models and views.
For instance, a standard page URL would be in the format:
/{pageurl}
Whereas a page URL for a blog page would be:
/blog/{pageurl}
This would make it very easy to distinguish between the two and route accordingly. If it matches the pattern /blog/*, it's a blog! However, let's assume you don't want to take the easiest method - but instead decide to have all URLs follow the same pattern: /{pageurl}. Your actual list of URLs should all be stored in a single table in the database, let's say it's named site_pages. The relationship between your site_pages and blogs would be a column in blogs named page_id that is a foreign-key back to the site_pages table.
With this, you have a few ways you could determine what type of page you're looking at:
Add a new column to site_pages table, such as is_blog; it it's set, you have a blog!
Every time you look up the page in the database, also get a count() of blog entries for the specific page; if it's > 0, you have a blog page. Otherwise display it as static content.
Make an assumption that if page_content is empty, it's a blog.
Once you have established if the page is a static page or a blog page, you could load a corresponding Model - "Page" or "BlogPage". BlogPage can, and probably should, extend Page since they have the same purpose. The only difference between the two is that "Page" just loads the page's text-content and the View simply writes it out. The "BlogPage", on the other hand, would load the list of Categories, Posts, etc and the View would iterate through them and display them however you see fit.
Related
I am building a website for a school using wordpress. What is the best way to construct the classes and the students for each year? And what is a good way to display them and navigate between each year and show the classes for each year?
I tried showing them all on the same page. But i want to categorize each class with its specific year and navigate through each year.
I assume every student has it's dedicated profile page.
If you want to use the default Wordpress hierarchy,
You can start by setting the pages dedicated for classes
Then you can set the year number as a category (or tag) for each class
Then for each student' page, you can set it's class page as a parent page. Using the page attributes like here
Later you will list all categories links in the main page.
But if you expect a custom design, like a timeline or a tree or a big hirearchy chart, you need to use page templates with custom queries.
I have a Home page on the Drupal website (such as is created after installation), but I still need to create this page:
What is the best way to create a page so that I can then add these posts with images?
I am just starting to learn Drupal and have heard so far about such ways of creating pages:
1) in admin toolbar: Content / Add Content / Article
2) in admin toolbar: Content / Add Content / Basic page
3) in admin toolbar: Structure / Views / Add Views
Which one should I use? Or maybe there is some other option that I don’t know about?
P.S. At the moment I am more interested how to create empty page on which I can then add posts later, and adding posts it is another question.
Welcome to Drupal.
Drupal ships with the default theme which won't look nice but it does its job in the right way. Now if you want to create a better UI/UX obviously you should create a new theme. But before that make sure to read and understand the concepts behind Drupal. Drupal docs are your first friend.
Drupal Documentation
Drupal considers everything as nodes and that's how Drupal got its power. As you mentioned, Articles, Basic Page etc are called content types and they can be used to create a particular type of content.
Now for your purpose create a new content type and add the fields you need. From the image above I can say your content type needs Title, Image, Category and Date. After creating content type you can create as many contents as you want under the content type you just created. Consider each card in your image as content.
Now you can use a Drupal Core Module Views, to perform DataBase Operations without writing single code. Yes, you can select fields, sort, order etc with Views UI and display it in a page or a part of a page (Block).
I would say just try this out in the default Drupal theme and when you understand how this works, you can start creating your own theme for your project.
Theming Drupal
There is a lot of resources available. But you have to make sure what you are asking is whether you actually need. It will take some time, but it worth.
To build layouts for homepages on Drupal 8 you best friend is https://www.drupal.org/docs/8/core/modules/layout-builder
To build the content blocks inside your home page, you should start creating nodes on a node content type to hold your information. For instance: news content type, with a title, a body, a date, and an image.
For every node type, ex. news, work on the preview display, full display, and any other display which makes sense. These displays can be used later in the Layout Builder directly or in Views, referenced below.
If you wish your list to be dynamic, such as the last 10 entries are shown first, then use a view to hold the content sorted and filtered as you need.
In a nutshell.
Create a content type for your article/news.
Modify the displays of the content types to have at least a summary and full view.
Create the content itself to have something to see.
Create the view (block) to filter and sort your content.
Create a page layout (this makes sense for landing pages) which places your new view and any other content you need in any disposition.
This is roughly what I would do. The steps described above contain many intermediate steps. If in doubt, check the docs.
I hope that helps!
First, decide what will you display on that page. Is it content in some existing content type (article maybe) or you want to crate new one for this purpose.
If you need new one then create it (Structure -> Content types -> Add content type).
Then check what fields will you need. I.e. image, some description text. Add missing ones.
Create few nodes (pages) in that type so you could work with them.
Then for displaying you should crate a view (Structure -> Views -> Add view). It can be a page view (you are displaying only that content on page) or block view (this is just a block among some others). If you create a page you could visit it and if you create a block you have to add it to some region to appear on page (Structure -> Block Layout).
Inside your theme you should create templates for this page/block. Turn on twig debug mode so it will show you hints - what templates are used and how can you name yours to override default ones.
Adjust CSS to make it look like you want it to look.
Find some tutorial(s) for the details
Previous answers have given the flow of the work you should go through, I would like to add some resource that might help you achieve this.
Creating content type and fields: https://www.drupal.org/docs/administering-a-drupal-site/managing-content-0/working-with-content-types-and-fields
https://www.drupal.org/docs/user_guide/en/structure-content-type.html
View and View modes: https://www.drupal.org/docs/user_guide/en/views-concept.html
https://www.drupal.org/docs/8/api/entity-api/display-modes-view-modes-and-form-modes
Handling block of the view: https://www.drupal.org/docs/8/core/modules/block/overview
Feel free to ask if any further explanation is needed.
Thank you
My customer has a Wordpress blog with a page named "Galleries" that serves as a kind of main page as he manually writes there links to other pages, both local and external.
The main menu for the blog has also a link to this Galleries page. Problem is that the menu item only is active for that page, but not for the linked local pages, unless you previously selected Galleries as their parent page.
So I was wondering if it will be possible (with a hook) to virtually force an ancestor to a page that meets certain conditions before the menu is rendered, avoiding the need to manually edit every page and make it a child to "Galleries"
You'd have to find a filter that works in the very early stage of assembling the menu data, or do some heavy array juggling once it's already build.
I'd suggest another approach:
Update the parent for all currently existing pages via a simple database query. wp_posts contains a column post_parent - so create a query that filters out all of your pages that satisfy the criteria you mentioned (how easy or hard that will be, depends on what your criteria are - might involve JOINs with other tables like wp_postmeta, wp_terms), and then update the parent for those. This is a one-time thing, so it can be done via phpMyAdmin or some database frontend like that. Keep in mind that since "pages" are ordinary posts internally, and stored in the same table, you will have to filter for only those posts that are pages in the first place.
Create a function that hooks into the post save/update actions, in there again check if the criteria are matched, and if so set the parent page for the post at that point in the PHP data structure, before it gets written away to the database.
Finally found how to do it:
$main_gallery_page= get_page_by_title('Galleries');
add_filter('nav_menu_css_class' , 'force_ancestor_nav_class' , 10 , 2);
function force_ancestor_nav_class($classes, $item){
global $main_gallery_page,$post;
//condition: could be any condition: by category, title, contents, ...
$make_ancestor=substr( $post->post_title, 0, 7 ) === "Gallery";
//only adds the class if the condition is met and not already present
if ($item->object_id==$main_gallery_page->ID && $make_ancestor && !in_array('current-page-ancestor',$classes)) {$classes[]='current-page-ancestor';}
return $classes;
}
I want to create a wordpress blog template. Like other themes have I don't just want one layout for my blog index page (home.php). I want to have the option that the user can select between 2 columns, 3 columns, some custom layout etc.
I know I could achieve this with static pages. But for the blog index there should not be static pages. So can anyone tell me how to achieve this?
I am not exactly sure what you are asking.
Do you want your users to be able to pick from different layouts? In that case, write the layouts in HTML(you can use a frontend framework like Bootstrap to help you), use PHP to detect the user's choice(storing it in a cookie, for instance, and setting the value of the cookie with a simple form and post), and echo only the layout you'd like.
If that's not what you're asking, please update your question with some examples.
I am using Symfony 1.2.9 (with Propel ORM) to create a website. I have started using the admin generator to implement the admin functionality.
I have come accross a slight 'problem' however. My models are related (e.g. one table may have several 1:N relations and N:N relations). I have not found a way to address this satisfactorily yet. As a tactical solution (for list views), I have decided to simply show the parent object, and then add interactions to show the related objects.
I'll use a Blog model to illustrate this.
Here are the relationships for a blog model:
N:M relationship with Blogroll (models a blog roll)
1:N relationship with Blogpost (models a post submitted to a blog)
I had originally intended on displaying the (paged) blogpost list for a blog,, when it was selected, using AJAX, but I am struggling enough with the admin generator as it is, so I have shelved that idea - unless someone is kind enough to shed some light on how to do this.
Instead, what I am now doing (as a tactical/interim soln), is I have added interactions to the list view which allow a user to:
View a list of the blog roll for the
blog on that row
View a list of the posts for the blog on that row
Add a post for the blog on tha row
In all of the above, I have written actions that will basically forward the request to the approriate action (admin generated). However, I need to pass some parameters (like the blog id etc), so that the correct blog roll or blog post list etc is returned.
I am sure there is a better way of doing what I want to do, but in case there isn't here are my questions:
How may I obtain the object that relates to a specific row (of the
clicked link) in the list view (e.g. the blog object in this example)
Once I have the object, I may choose to extract various fields: id etc.
How can I pass these arguments to the admin generated action ?
Regarding the second question, my guess is that this may be the way to do it (I may be wrong)
public function executeMyAddedBlogRollInteractionLink(sfWebRequest $request)
{
// get the object *somehow* (I'm guessing this may work)
$object = $this->getRoute()->getObject();
// retrieve the required parameters from the object, and build a query string
$query_str=$object->getId();
//forward the request to the generated code (action to display blogroll list in this case)
$this->forward('backendmodulename',"getblogrolllistaction?params=$query_string");
}
This feels like a bit of a hack, but I'm not sure how else to go about it. I'm also not to keen on sending params (which may include user_id etc via a GET, even a POST is not that much safer, since it is fairly sraightforward to see what requests a browser is making). if there is a better way than what I suggest above to implement this kind of administration that is required for objects with 1 or more M:N relationships, I will be very glad to hear the "recommended" way of going about it.
I remember reading about marking certain actions as internal. i.e. callable from only within the app. I wonder if that would be useful in this instance?
I'm assuming your application is called backend. Suppose there are two models, BlogPost and BlogPostComment. These are managed using admin generated modules called blog_post and blog_post_comment.
I believe you want a link against each BlogPost displayed on the list page at backend.php/blog_post. The links take you to backend.php/blog_post_comment, which should only show comments related to the relevant BlogPost.
Under apps/backend/blog_post/templates, create a file called _commentslink.php and put this in it:
View Comments
Then in apps/backend/blog_post/config/generator.yml, you need to include this partial in the fields for the list view:
....
param:
config:
list:
display: [ id, title, _commentslink ]
Note the _commentslink - the _ tells it to use a partial instead of looking for the field in the model. Your object is available in this partial as $<name of model> - $blog_post in this case.
Essentially, all this method does is links to the same action as the filter on the comments list normally goes to, passing the relevant condition to it to make it filter by blogpost_id.
If you've got CSRF protection enabled in the backend, you'll need to disable it, or this method won't work. This is set in apps/backend/config/settings.yml. There will be a setting in there called csrf_secret - it should be set to false to disable csrf.
You should try symfony 1.3/1.4 out if you need support for 1:N relationships in forms. 1.3 is in my experience a relatively hassle free upgrade from 1.2.x - 1.4 is the same, but with deprecated features removed.