5

I need to add a specific CSS file to a CMS page using Magento 2. I am wanting to achieve this by using the Layout Update XML area in the admin. However, I cannot figure out or find any working examples of just how to do this.

My home page CMS is the page I am trying to add the CSS to. I can add specific CSS files in the head of the entire site by calling them out in the default_head_blocks.xml. But in this case I need it to be used on ONLY the home page CMS.

It appears as though I should be using <referenceContainer> but after that I am not sure what to do.

8

The solution I found was to create an XML file specifically called cms_index_index.xml.
Inside that file I was able to simply call the css I needed

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <head>
        <css src="css/mycustom.css" after="-" />
    </head>
</page>
4

3 hours later...

Create Module Folder Structure:

app / code / [Vendor] / [ModuleName]

app / code / [Vendor] / [ModuleName] / etc

app / code / [Vendor] / [ModuleName] / view / frontend / layout

Create Module Files:

app / code / [Vendor] / [ModuleName] / registration.php

app / code / [Vendor] / [ModuleName] / etc / module.xml

app / code / [Vendor] / [ModuleName] / view / frontend / layout / cms_index_index.xml

registration.php

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'[Vendor]_[ModuleName]',
__DIR__
);

module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../vendor/magento/framework/Module/etc/module.xsd">
<module name="[Vendor]_[ModuleName]" setup_version="0.0.1" />
</config>

Enable Module (SSH to magento root):

php -f bin/magento module:enable --clear-static-content [Vendor]_[ModuleName]

php -f bin/magento setup:upgrade

cms_index_index.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../vendor/magento/framework/Module/etc/module.xsd">
<head>
    <css src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" src_type="url" />
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" src_type="url" />
</head>
</page>

Deploy static resources (SSH to magento root):

php bin/magento setup:static-content:deploy

Page Source Results:

<link  rel="stylesheet" type="text/css"  media="all" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />

<script  type="text/javascript"  src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
3

If you want to add the specific CSS only for a CMS page and not for all CMS page :

You can add Layout Update XML update for your CMS page here: admin ->CMS -> Pages -> Design -> XML Layout Update

With the content :

<head>
  <css src="Namespace_YourModule::css/yourfile.css"/>
</head>

Then there is a bug in Magento 2, you need to override the default Magento 2 vendor/magento/framework/View/Layout/etc/page_layout.xsd validation file.

A workaround, not a clean solution, but waiting Magento 2 to allow override xsd files

app/code/Vendor/Module/etc/di.xml

<preference for="Magento\Framework\View\Model\Layout\Update\Validator" type="Vendor\Module\Model\Layout\Update\Validator" />

app/code/Vendor/Module/etc/page_layout.xsd

<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
 * Copyright © 2013-2017 Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:include schemaLocation="urn:magento:framework:View/Layout/etc/elements.xsd"/>
    <xs:include schemaLocation="urn:magento:framework:View/Layout/etc/head.xsd"/>
    <xs:include schemaLocation="urn:magento:framework:View/Layout/etc/body.xsd"/>

    <xs:complexType name="pageLayoutType">
        <xs:sequence minOccurs="0" maxOccurs="unbounded">
            <xs:element ref="referenceContainer" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element ref="container" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element ref="update" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element ref="move" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element name="head" type="headType" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element name="body" type="bodyType" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>

    <xs:element name="layout" type="pageLayoutType">
        <xs:unique name="containerKey">
            <xs:selector xpath=".//container"/>
            <xs:field xpath="@name"/>
        </xs:unique>
    </xs:element>
</xs:schema>

app/code/Vendor/Module/Model/Layout/Update/Validator.php

<?php
namespace Hublot\Setup\Model\Layout\Update;

use Magento\Framework\Config\Dom\UrnResolver;

class Validator extends \Magento\Framework\View\Model\Layout\Update\Validator
{
    const LAYOUT_SCHEMA_PAGE_HANDLE = 'page_layout';

    const LAYOUT_SCHEMA_MERGED = 'layout_merged';

    /**
     * @param \Magento\Framework\Config\DomFactory $domConfigFactory
     * @param \Magento\Framework\Config\Dom\UrnResolver $urnResolver
     */
    public function __construct(
        \Magento\Framework\Config\DomFactory $domConfigFactory,
        UrnResolver $urnResolver
    ) {
        $this->_domConfigFactory = $domConfigFactory;
        $this->_initMessageTemplates();
        $this->_xsdSchemas = [
            self::LAYOUT_SCHEMA_PAGE_HANDLE => $urnResolver->getRealPath(
                'urn:hublot:module:Hublot_Setup:etc/page_layout.xsd'
            ),
            self::LAYOUT_SCHEMA_MERGED => $urnResolver->getRealPath(
                'urn:magento:framework:View/Layout/etc/layout_merged.xsd'
            ),
        ];
    }
}

EDIT : This error seems to be fixed in Magento 2.1.9 or 2.2.0

1

I just added :

 <link href="path/to/custom.css" media="all" type="text/css" rel="stylesheet">

on the content tab of the CMS page.

1

Searched all over the web for this answer, finally got it through a lot of experimentation.

I believe this to be the easiest way:
Go to the page located in the Admin panel.
Find your page and scroll down past the content section to the layout update xml section.
In that box you can add page specific CSS and JS.

<head> <css src="js/ingredients.css> </head>  

This will add your script to the top of the head section.
(Making things tricky for your JS)

<head><script src="requirejs/require.js"/><script src="js/ingredients.js"/></head>  

^Above you will notice that I added the requirejs file first. This is done because without adding it before your personalized JS file, you will not be able to access the other libraries loaded into requirejs.

0

In your local.xml file in your theme layout folder you can target all cms pages using the <cms_page> tag or just the homepage with <cms_index_index>

EX:

<!-- anything in default applies to all -->
<default>
   ... stuff that effects all pages goes here
</default>
<!-- changes in cms_index_index will only apply to the homepage -->
<cms_index_index>
    <reference name="head">
       <action method="addCss">
          <stylesheet>css/custom.css</stylesheet>
       </action>
    </reference>
<cms_index_index>
-1

Try this in your In admin ->CMS -> Pages -> Design -> XML Layout Update

<reference name="head">
   <action method="addCss">
      <stylesheet>css/custom.css</stylesheet>
   </action>
</reference>
  • My mistake for not adding that I am trying to accomplish this in Magento 2. Your solution was the first thing I tried. When I got errors I started to look up how to override layouts in the devdocs. Your solution works great in Magento 1.X but not Magento 2 – Gary Mar 22 '16 at 19:54
  • Try this <head> <css src="mage/gallery/styles-view.css"/> </head> – Magento 2 Mar 22 '16 at 20:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.