Mojo::Path - Path


Mojolicious documentation Contained in the Mojolicious distribution.

Index


Code Index:

NAME

Top

Mojo::Path - Path

SYNOPSIS

Top

  use Mojo::Path;

  my $path = Mojo::Path->new('/foo/bar%3B/baz.html');
  shift @{$path->parts};
  print "$path";

DESCRIPTION

Top

Mojo::Path is a container for URL paths.

ATTRIBUTES

Top

Mojo::Path implements the following attributes.

leading_slash

  my $leading_slash = $path->leading_slash;
  $path             = $path->leading_slash(1);

Path has a leading slash.

parts

  my $parts = $path->parts;
  $path     = $path->parts(qw/foo bar baz/);

The path parts.

trailing_slash

  my $trailing_slash = $path->trailing_slash;
  $path              = $path->trailing_slash(1);

Path has a trailing slash.

METHODS

Top

Mojo::Path inherits all methods from Mojo::Base and implements the following new ones.

new

  my $path = Mojo::Path->new;
  my $path = Mojo::Path->new('/foo/bar%3B/baz.html');

Construct a new Mojo::Path object.

append

  $path = $path->append(qw/foo bar/);

Append parts to path.

canonicalize

  $path = $path->canonicalize;

Canonicalize path.

clone

  my $clone = $path->clone;

Clone path.

parse

  $path = $path->parse('/foo/bar%3B/baz.html');

Parse path.

to_abs_string

  my $string = $path->to_abs_string;

Turn path into absolute string. Note that this method is EXPERIMENTAL and might change without warning!

to_string

  my $string = $path->to_string;

Turn path into a string.

SEE ALSO

Top

Mojolicious, Mojolicious::Guides, http://mojolicio.us.


Mojolicious documentation Contained in the Mojolicious distribution.

package Mojo::Path;
use Mojo::Base -base;
use overload
  'bool'   => sub {1},
  '""'     => sub { shift->to_string },
  fallback => 1;

use Mojo::Util qw/url_escape url_unescape/;
use Mojo::URL;

has [qw/leading_slash trailing_slash/] => 0;
has parts => sub { [] };

sub new {
  my $self = shift->SUPER::new();
  $self->parse(@_);
  $self;
}

sub append {
  my $self = shift;

  for (@_) {
    my $value = "$_";

    # *( pchar / "/" / "?" )
    url_escape $value, $Mojo::URL::PCHAR;

    push @{$self->parts}, $value;
  }

  $self;
}

sub canonicalize {
  my $self = shift;

  # Resolve path
  my @path;
  for my $part (@{$self->parts}) {

    # ".."
    if ($part eq '..') {

      # Leading '..' can't be resolved
      unless (@path && $path[-1] ne '..') { push @path, '..' }

      # Uplevel
      else { pop @path }
      next;
    }

    # "."
    next if $part eq '.';

    push @path, $part;
  }
  $self->parts(\@path);

  $self;
}

# "Homer, the plant called.
#  They said if you don't show up tomorrow don't bother showing up on Monday.
#  Woo-hoo. Four-day weekend."
sub clone {
  my $self = shift;

  my $clone = Mojo::Path->new;
  $clone->parts([@{$self->parts}]);
  $clone->leading_slash($self->leading_slash);
  $clone->trailing_slash($self->trailing_slash);

  $clone;
}

sub parse {
  my ($self, $path) = @_;

  # Leading and trailing slash
  $path = '' unless defined $path;
  $path =~ /^\// ? $self->leading_slash(1)  : $self->leading_slash(0);
  $path =~ /\/$/ ? $self->trailing_slash(1) : $self->trailing_slash(0);

  # Parse
  url_unescape $path;
  my @parts;
  for my $part (split '/', $path) {

    # Empty parts before the first are garbage
    next unless length $part or scalar @parts;

    # Empty parts behind the first are ok
    $part = '' unless defined $part;

    push @parts, $part;
  }
  $self->parts(\@parts);

  $self;
}

sub to_abs_string {
  my $self = shift;
  return $self->to_string if $self->leading_slash;
  '/' . $self->to_string;
}

sub to_string {
  my $self = shift;

  # Escape
  my @path;
  for my $part (@{$self->parts}) {

    # *( pchar / "/" / "?" )
    my $escaped = $part;
    url_escape $escaped, $Mojo::URL::PCHAR;
    push @path, $escaped;
  }

  # Format
  my $path = join '/', @path;
  $path = "/$path" if $self->leading_slash;
  $path = "$path/" if @path && $self->trailing_slash;

  $path;
}

1;
__END__