0

I am trying to make dynamic pages using hook menu which is going fine but the problem is I want to add page arguments for the states. For example if someone goes to the url and there isnt a state in the url like california for example(site/listings/california) it would show a page not found error, and if found it would list the listings I have looped out in my function.

Any Suggestions?

/*
** Hook Menu
*/

function listings_menu() {
    $items = array();

    $items['site/listings/%'] = array(
        'title' => 'City Listings',
        'page callback' => 'business_listings',
        'access arguments' => array('access content'),
        'page arguments' => array('states', 'city_names'),
    );

    return $items;
}


/*
** State Listings
*/

function listing_states($state){
    $state = array( 
        'alabama' => t('Alabama'),
        'alaska' => t('Alaska'),
        'arizona' => t('Arizona'),
    //ect.....

    );
    return $state;
}

/*
** Company Listings
*/

function business_listings(){

    $states = listing_states(arg(2));

    $dbquery = db_query("SELECT DISTINCT CityName FROM {zipcodes} WHERE StateName = '".ucfirst(arg(2))."' ORDER BY CityName ASC");

    $cityname = '';
    $cityname .= '<div class="city-wrapper">';
    foreach ($dbquery as $dbrow) {
        $cityname .='<div class="cityname" style="float:left; width:200px;">';
        $cityname .= '<a href="'.arg(2).'/'.strtolower(urlencode($dbrow->CityName)).'">'.$dbrow->CityName.'</a>';
        $cityname .= '</div>';
    }
    $cityname .= '</div>';

    return array('states' => $states, 'city_names' => $cityname);
}

2 Answers 2

1

Update your menu callback to pass the third argument (state) to the page callback:

$items['site/listings/%'] = array(
  'title' => 'City Listings',
  'page callback' => 'business_listings',
  'access arguments' => array('access content'),
  'page arguments' => array(2),
);

Then update your page callback to use the new argument, validate it against the items returned by listing_states() (which doesn't look like it needs to accept an argument), and throw a 404 if validation fails:

/**
 * State Listings
 */
function listing_states() {
  $states = array( 
    'alabama' => t('Alabama'),
    'alaska' => t('Alaska'),
    'arizona' => t('Arizona'),
    // ...
  );

  return $states;
}

/**
 * Company Listings
 */
function business_listings($state) {
  $all_states = listing_states();

  if (!isset($all_states[$state])) {
    drupal_not_found();
  }

  // your other code here
}

Additionally, you should really read up on Drupal's coding best practices, as there are numerous issues with your code. Other than formatting, your query is vulnerable to a SQL injection attack, your markup should be in a template file or a theme function, your CSS should be in an external CSS file, and your link should be using the l() function (or at least url() for the href attribute).

1
  • Thanks, yeah I know this is pretty sloppy, this is just a rough draft of the code, you know how it is when time is against you lol. Commented Jan 30, 2014 at 20:29
1

I believe you want to change your listings_menu()

function listings_menu() {
    $items = array();

    $items['site/listings/%'] = array(
        'title' => 'City Listings',
        'page callback' => 'business_listings',
        'access arguments' => array('access content'),
        'page arguments' => array(3),
    );

    return $items;
}

Then you need to change your listings to accept that argument

function business_listings($states){
  $states = listing_states($states);

  $dbquery = db_query("SELECT DISTINCT CityName FROM {zipcodes} WHERE StateName = '".ucfirst(arg(2))."' ORDER BY CityName ASC");

  $cityname = '';
  $cityname .= '<div class="city-wrapper">';
  foreach ($dbquery as $dbrow) {
      $cityname .='<div class="cityname" style="float:left; width:200px;">';
      $cityname .= '<a href="'.arg(2).'/'.strtolower(urlencode($dbrow->CityName)).'">'.$dbrow->CityName.'</a>';
      $cityname .= '</div>';
  }
  $cityname .= '</div>';

  return array('states' => $states, 'city_names' => $cityname);
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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