Skip to content
Yannick Warnier edited this page Nov 6, 2023 · 1 revision

This is an example, as a matter of "internal" developer documentation, on how to add page types to the CMS feature for admins.

We'll take this commit of an early stage development version of Chamilo as an example: https://github.com/chamilo/chamilo-lms/commit/87267615e616d4e4c2ea38042a6e24f863d629f4

Fixtures

Any page requires a page category, and a page category exists by the virtue of a record in the page_category table. But if you want the Chamilo installer/upgrader to come with that page category pre-created, you will have to hack into src/CoreBundle/Component/Utils/CreateDefaultPages.php and add a block of this kind to the createDefaultPages() method:

        $indexCategory = (new PageCategory())
            ->setTitle('demo')
            ->setType('grid')
            ->setCreator($user)
        ;
        $this->pageCategoryRepository->update($indexCategory);

To insert the record directly in the database, you would have something like this:

INSERT INTO page_category (creator_id, title, type, created_at, updated_at) VALUES (1,'demo','grid',NOW(),NOW());

Vue page

To vue the content itself, you will have to create a .vue page that (in this case) benefits from the PageCardList Vue component. For example, you could copy assets/vue/pages/Contact.vue to assets/vue/pages/Demo.vue and ensure all references to 'Contact' (in any lower/uppercase style) are changed to 'Demo'.

vue/router/index.js

Now you can create a new index entry for Vue to find the new component, by copying a block like the one for contact, to a similar block for demo:

    {
      path: "/demo",
      name: "Demo",
      component: Demo,
      meta: {
        requiresAuth: false,
        showBreadcrumb: false,
      },
    },

Symfony's IndexController

Now because we're using Symfony and the whole thing needs to be somewhat supported by Symfony (so it can answer with the micro-services necessary to populate the Vue views), we also need to declare the new page into the IndexController of Symfony (src/CoreBundle/Controller/IndexController.php). Ideally copying the nearest, most similar entry (in this case 'Contact' as we already did for the rest).

     * @Route("/contact", name="contact", methods={"GET", "POST"}, options={"expose"=true})
     * @Route("/demo", name="demo", methods={"GET", "POST"}, options={"expose"=true})

Now you can refresh Symfony's cache with a happy

php bin/console cache:clear

Updating the menu

If you want this new page type to appear in the public menu (before login), you will also need to update assets/vue/components/layout/TopbarNotLoggedIn.vue to add the entry. This is easily done in const menuItems by adding this block right after 'Contact':

  {
    label: "Demo",
    to: { name: "Demo" },
  },

Note that we use to:, not url:. This will enable Vue to directly load the content rather than reloading the complete page. It will make it faster and smoother, so use it if the component is managed by Vue anyway.

Translations

If you want the menu terms to be translated depending on the chosen language for the interface, you want the "label" in the menu above to be using a term managed by Chamilo translations (so you don't have to create a new one). If, as is the case here, the term exists in translations/messages.en.po but not in assets/locales/en.json, you will have to follow the procedure described here: https://github.com/chamilo/chamilo-lms/wiki/Internationalization#frontend-translations That is, you will need to create the entry manually in en.json (using the same term as in messages.en.po) and then launch:

php bin/console chamilo:update_vue_translations

Building

Now we've done a lot of updates to the Vue part, it's time to refresh Vue's JS build by issueing a (hopefully quick):

yarn dev

Creating the page

The menu should be updated and a new page type should now be available to your admin account at chamilo/admin -> Platform management -> Pages (hamburger menu on the top right to create a new page).

Once created in the right category and the right language, it should appear when you click the menu entry as a non-authenticated user.

Enjoy!

Clone this wiki locally