Giter Site home page Giter Site logo

Comments (11)

Log1x avatar Log1x commented on August 17, 2024 1

Is the registered navigation called offcanvas like you have one primary_navigation? If so you'd use Navi:build('offcanvas')->toArray()

from navi.

fabianwurk avatar fabianwurk commented on August 17, 2024 1

Thats solved it perfectly 🙌.

Many Thanks 👍

from navi.

minemindmedia avatar minemindmedia commented on August 17, 2024

@fabianwurk -- I'm trying to add 4 different menus and I came across this posting but haven't trouble setting up my file. Could you explain how you did this?

from navi.

fabianwurk avatar fabianwurk commented on August 17, 2024

Yeah sure, so in my:

setup.php I just register navs as normal eg

register_nav_menus([
    'primary' => __('Primary', 'sage'),
    'offcanvas' => __('Offcanvas', 'sage'),
    'footer' => __('Footer', 'sage'),
]);

then in Composers > Navigation.php

<?php

namespace App\View\Composers;

use Roots\Acorn\View\Composer;
use Log1x\Navi\Facades\Navi;

class Navigation extends Composer
{
    /**
     * List of views served by this composer.
     *
     * @var array
     */
    protected static $views = [
        'partials.header.nav.primary',
        'partials.header.nav.offcanvas',
        'partials.footer.footer',
    ];

    /**
     * Data to be passed to view before rendering.
     *
     * @return array
     */
    public function with()
    {
        return [
            'primary' => $this->primary(),
            'offcanvas' => $this->offcanvas(),
            'footer' => $this->footer(),
        ];
    }

    /**
     * Returns the primary navigation.
     *
     * @return array
     */
    public function primary()
    {
        if (Navi::build('primary')->isEmpty()) {
            return;
        }
        
        return Navi::build('primary')->toArray();
    }

    /**
     * Returns the offcanvas navigation.
     *
     * @return array
     */
    public function offcanvas()
    {
        if (Navi::build('offcanvas')->isEmpty()) {
            return;
        }
        
        return Navi::build('offcanvas')->toArray();
    }
    
    /**
     * Returns the footer navigation.
     *
     * @return array
     */
    public function footer()
    {
        if (Navi::build('footer')->isEmpty()) {
            return;
        }
        
        return Navi::build('footer')->toArray();
    }
}

then in primary.blade.php

@if ($primary)
<div x-data="{ open: false }">
  <nav :class="{'flex': open, 'hidden': !open}" class="hidden pb-4 md:pb-0 lg:flex lg:justify-end lg:flex-row">
  <ul class="flex text-white text-sm">
    @foreach ($primary as $item)
      @if ($item->children)

        <li @click.away="open = false"
        class="relative ml-4 mr-1 hover:text-tcol"
        x-data="{ open: false, timeout: null }"
        x-on:mouseenter="open = true; clearTimeout(timeout)"
        x-on:mouseleave="timeout = setTimeout(() => { open = false }, 100)"
        >
          <button @click="open = !open" class="flex flex-row">
          <a class="tracking-widest focus:outline-none uppercase {{ $item->classes ?? '' }} {{ $item->active ? 'text-tcol border-b-2 border-tcol pb-2' : '' }}" href="{{ $item->url }}">
            {{ $item->label }}
          </a>
          <svg
            viewBox="0 0 24 12"
            :class="{'rotate-180': open, 'rotate-0': !open}"
            class="inline w-4 h-4 transition-transform duration-200 transform text-white"
            x-cloak
            >
            <path d="M12 9.67a.68.68 0 01-.48-.19l-6-6a.68.68 0 011-1L12 8l5.52-5.52a.68.68 0 011 1l-6 6a.68.68 0 01-.52.19z" fill="currentColor"/>
          </svg>
          </button>

          <div
            x-show="open"
            class="absolute left-0 w-full mt-2 origin-top-right shadow-lg md:w-40 z-30"
            style="display: none;"
          >
            <ul class="p-3 bg-white rounded-md shadow-2xl">
              @foreach ($item->children as $child)
                <li @click.away="open = false"
                class="relative py-2" style="padding-top: 10px;"
                x-data="{ open: false, timeout: null }"
                x-on:mouseenter="open = true; clearTimeout(timeout)"
                x-on:mouseleave="timeout = setTimeout(() => { open = false }, 100)"
                >
                <button @click="open = !open">
                  <span class="flex justify-between">
                    <a class="text-pcol" href="{{ $item->url }}">
                      {{ $child->label }}
                    </a>
                    @if ($child->children)
                    <svg class="text-scol pl-2" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg" width="24" height="20"><path d="M13.5 7.5l-4-4m4 4l-4 4m4-4H1" stroke="currentColor" stroke-linecap="square"></path></svg>
                    @endif
                  </span>
                </button>

                  <div
                    x-show="open"
                    style="display: none;"
                    class="transition duration-500 ease-in-out"
                  >
                    @if ($child->children)
                    <ul class="absolute bg-white shadow-xl rounded-tr rounded-br rounded-bl w-48 p-4" style="left: 143px; top: -12px;">
                      @foreach ($child->children as $secondChild)
                      <li class="grid py-2">
                        <a class="text-pcol hover:text-scol {{ $item->classes ?? '' }} {{ $item->active ? '' : '' }}" href="{{ $item->url }}">
                          {{ $secondChild->label }}
                        </a>
                      </li>
                      @endforeach
                    </ul>
                    @endif
                  </div>

              </li>
              @endforeach
            </ul>
          </div>

        </li>

      @else
      <li class="mx-4 hover:text-tcol">
        <a class="tracking-widest focus:outline-none uppercase {{ $item->classes ?? '' }} {{ $item->active ? 'text-tcol border-b-2 border-tcol pb-2' : '' }}" href="{{ $item->url }}">
          {{ $item->label }}
        </a>
      </li>
      @endif
    @endforeach
    </ul>
  </nav>
</div>

@endif

And just add any other nav you need eg. offcanvas or footer.

(ps. I use Tailwindcss and Alpine.js for styling and reactiveness).

from navi.

minemindmedia avatar minemindmedia commented on August 17, 2024

@fabianwurk thanks for that! I was mostly curious how you setup your navigation composer. That's how I am doing it as well but I'm getting:

ErrorException (E_ERROR)
array_filter() expects parameter 1 to be array, bool given

from navi.

Log1x avatar Log1x commented on August 17, 2024

@minemindmedia what plugins are you using? can you show an example of your code?

from navi.

minemindmedia avatar minemindmedia commented on August 17, 2024

This project is using these plugins:

    "advanced-custom-fields/advanced-custom-fields-pro": "*",
    "deliciousbrains-plugin/wp-migrate-db-pro": "1.9.13",
    "deliciousbrains-plugin/wp-migrate-db-pro-media-files": "^1.4",
    "deliciousbrains-plugin/wp-migrate-db-pro-multisite-tools": "^1.2",
    "wpackagist-plugin/woocommerce": "4.9.0",
    "wpackagist-plugin/safe-svg":"1.9.9",
    "minemindmedia/filter-keys": "@dev",
    "satispress/ninja-forms": "3.4.34",
    "satispress/ninja-forms-conditionals": "3.0.28",
    "satispress/ninja-forms-multi-part": "3.0.26",
    "satispress/ninja-forms-style": "3.0.28",
    "satispress/ninja-forms-post-creation": "3.0.10",
    "satispress/advanced-forms-pro": "1.6.6"

Navigation.php


<?php

namespace App\View\Composers;

use Roots\Acorn\View\Composer;
use Log1x\Navi\Facades\Navi;

class Navigation extends Composer
{

    protected static $views = [
        'partials.navigation.main-menu',
        'partials.navigation.account-menu',
    ];

    public function with()
    {
        return [
            'main_menu' => $this->main(),
            'account_menu' => $this->account(),
        ];
    }

    public function main()
    {
        if (Navi::build('main_menu')->isEmpty()) {
            return;
        }
        
        return Navi::build('main_menu')->toArray();
    }

    public function account()
    {
        if (Navi::build('account_menu')->isEmpty()) {
            return;
        }
        
        return Navi::build('account_menu')->toArray();
    }
    
}

main-menu.blade.php

@if ($main_menu)
  <ul class="my-menu">
    @foreach ($main_menu as $item)
      <li class="my-menu-item {{ $item->classes ?? '' }} {{ $item->active ? 'active' : '' }}">
        <a href="{{ $item->url }}">
          {{ $item->label }}
        </a>

        @if ($item->children)
          <ul class="my-child-menu">
            @foreach ($item->children as $child)
              <li class="my-child-item {{ $child->classes ?? '' }} {{ $child->active ? 'active' : '' }}">
                <a href="{{ $child->url }}">
                  {{ $child->label }}
                </a>
              </li>
            @endforeach
          </ul>
        @endif
      </li>
    @endforeach
  </ul>
@endif

account-menu.blade.php


@if ($account_menu)
  <li class="inline-flex ml-4">
    @foreach ($account_menu as $item)
    @php $icon = get_field('svg_icon', $item) @endphp
      <div class="flex">
        <div x-data="{ returns: false }" class="relative" x-cloak>
          <div x-on:click="returns = true" class="flex text-white hover:text-primary-200 cursor-pointer">
            <span class="inline-flex w-4 h-4 self-center mr-1">{!! get_field('svg_icon', $item->id) !!}</span>
            {{ $item->label }}
            <svg class="inline w-5 h-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
            </svg>
          </div>
          @if ($item->children)
            <div x-show.transition="returns" x-on:click.away="returns = false" class="absolute right-0 mt-2.5 py-2 bg-white border-b rounded shadow-xl z-50 space-y-2">   
              @foreach ($item->children as $child)
                <a href="{{ $child->url }}" class="flex transition-colors duration-200 px-4 py-1 text-normal text-gray-900 hover:text-primary-700 whitespace-nowrap">    
                  <span class="inline-flex w-4 h-4 self-center mr-2">{!! get_field('svg_icon', $child->id) !!}</span>
                  {{ $child->label }}
                </a>
              @endforeach
            </div>
          @endif
        </div>
      </div>
    @endforeach
  </li>
@endif

setup.php

    register_nav_menus([
        'main_menu' => __('Main Menu', 'sage'),
        'account_menu' => __('Account Menu', 'sage'),
        'support_menu' => __('Support Menu', 'sage'),
        'returns_menu' => __('Returns Menu', 'sage'),
    ]);

from navi.

fabianwurk avatar fabianwurk commented on August 17, 2024

I have added your code in my setup and getting no errors.

Screenshot 2021-03-02 at 09 37 05

from navi.

minemindmedia avatar minemindmedia commented on August 17, 2024

Weird.

If I remove the main-menu and just keep the account menu, I get the same error.

<?php

namespace App\View\Composers;

use Roots\Acorn\View\Composer;
use Log1x\Navi\Facades\Navi;

class Navigation extends Composer
{

    protected static $views = [
        'partials.navigation.account-menu',
    ];

    public function with()
    {
        return [
            'account-menu' => $this->account(),
        ];
    }

    public function account()
    {
        if (Navi::build('account_menu')->isEmpty()) {
            return;
        }
        
        return Navi::build('account_menu')->toArray();
    }
    
}

Here's more error details:
/srv/www/project.com/current/web/app/themes/cck/vendor/log1x/navi/src/MenuBuilder.php

image

If I remove account menu, then the page loads the main menu.


<?php

namespace App\View\Composers;

use Roots\Acorn\View\Composer;
use Log1x\Navi\Facades\Navi;

class Navigation extends Composer
{

    protected static $views = [
        'partials.navigation.main-menu',
        'partials.navigation.account-menu',
    ];

    public function with()
    {
        return [
            'main_menu' => $this->main(),
        ];
    }

    public function main()
    {
        if (Navi::build('main_menu')->isEmpty()) {
            return;
        }
        
        return Navi::build('main_menu')->toArray();
    }
    
}

from navi.

Log1x avatar Log1x commented on August 17, 2024

What items do you have on your account menu? Are they from a plugin? If so which one? Nonetheless I will push something to the code to prevent the exception from being thrown here – but in this scenario without figuring out the underlying issue I feel like your menu will just end up empty.

from navi.

minemindmedia avatar minemindmedia commented on August 17, 2024

Hi Brandon, for some reason the display location was unchecked. That's what causes this error. Now its working of course. Stupid mistake by me.

image

from navi.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.