Arama widget'ıyla arama arayüzü oluşturma

Arama widget'ı, web uygulamaları için özelleştirilebilir bir arama arayüzü sağlar. Widget, yalnızca küçük bir miktar HTML ve JavaScript özellikler ve sayfalara ayırma gibi yaygın arama özelliklerini uygular ve etkinleştirir. Siz ayrıca arayüzün bölümlerini CSS ve JavaScript ile özelleştirebilirsiniz.

Widget'ın sunduğundan daha fazla esnekliğe ihtiyacınız varsa Sorgu API'si. Query API ile arama arayüzü oluşturma hakkında bilgi için Query API ile arama arayüzü oluşturma bölümüne bakın.

Arama arayüzü oluşturma

Arama arayüzünü oluşturmak için birkaç adım gerekir:

  1. Bir arama uygulamasını yapılandırma
  2. Uygulama için istemci kimliği oluşturma
  3. Arama kutusu ve sonuçlar için HTML işaretlemesi ekleme
  4. Sayfada widget'ı yükle
  5. Widget'ı başlatma

Bir arama uygulamasını yapılandırma

Her arama arayüzünün Yönetici Konsolu. Arama uygulaması, DMAIC ve PDCA gibi sorguyla ilgili bilgileri (ör. veri kaynakları, özellikler ve ve arama kalitesi ayarlarına gidin.

Bir arama uygulaması oluşturmak için Özel arama deneyimi oluşturun.

Uygulama için istemci kimliği oluşturma

Bu adımların yanı sıra Google Cloud Search API'ye erişimi yapılandırın, ayrıca web uygulaması için de bir istemci kimliği oluşturmalısınız.

Proje yapılandırma

Projeyi yapılandırdığınızda:

  • Web tarayıcısı istemci türünü seçin
  • Kaynak URI'yi sağlayın en iyi yoludur.
  • Oluşturulan istemci kimliğini not edin. Aşağıdaki işlemler için istemci kimliğiniz gerekir: sonraki adımları tamamlayın. İstemci gizli anahtarı widget'ını tıklayın.

Daha fazla bilgi için bkz. İstemci Tarafı Web Uygulaması için OAuth 2.0.

HTML işaretlemesi ekleyin

Widget'ın çalışması için az miktarda HTML gerekir. Siz şunları sağlamalıdır:

  • Arama kutusu için input öğesi.
  • Öneri pop-up'ının bağlanacağı öğe.
  • Arama sonuçlarını içerecek öğe.
  • (İsteğe bağlı) Özellik kontrollerini içerecek bir öğe sağlayın.

Aşağıdaki HTML snippet'i bir arama widget'ına ilişkin HTML'yi gösterir. Burada bağlanacak öğeler id özellikleriyle tanımlanır:

serving/widget/public/with_css/index.html
<div id="search_bar">
  <div id="suggestions_anchor">
    <input type="text" id="search_input" placeholder="Search for...">
  </div>
</div>
<div id="facet_results"></div>
<div id="search_results"></div>

Widget'ı yükleyin

Widget, bir yükleyici komut dosyası aracılığıyla dinamik olarak yüklenir. Dahil edilecek <script> etiketini aşağıda gösterildiği gibi kullanın:

serving/widget/public/with_css/index.html
<!-- Google API loader -->
<script src="https://apis.google.com/js/api.js?mods=enable_cloud_search_widget&onload=onLoad" async defer></script>

Komut dosyası etiketinde onload geri çağırması sağlamanız gerekir. Fonksiyona hazır olduğunu anlayabilirsiniz. Yükleyici hazır olduğunda widget'ı yüklemeye devam edin gapi.load() çağrısı yaparak API istemcisi, Google ile Oturum Açma ve Cloud Search modüllerini yükleyebilirsiniz.

serving/widget/public/with_css/app.js
/**
* Load the cloud search widget & auth libraries. Runs after
* the initial gapi bootstrap library is ready.
*/
function onLoad() {
  gapi.load('client:auth2:cloudsearch-widget', initializeApp)
}

initializeApp() işlevi, tüm modüller tamamlandıktan sonra çağrılır yüklendi.

Widget'ı başlatma

Öncelikle, şunu çağırarak istemci kitaplığını başlatın: Oluşturulan istemci kimliğinizle gapi.client.init() veya gapi.auth2.init() ve https://www.googleapis.com/auth/cloud_search.query kapsamı. Sonra, gapi.cloudsearch.widget.resultscontainer.Builder ve Widget'ı yapılandırmak için gapi.cloudsearch.widget.searchbox.Builder sınıf HTML öğelerinize bağlamanız gerekir.

Aşağıdaki örnekte widget'ın nasıl başlatılacağı gösterilmektedir:

serving/widget/public/with_css/app.js
/**
 * Initialize the app after loading the Google API client &
 * Cloud Search widget.
 */
function initializeApp() {
  // Load client ID & search app.
  loadConfiguration().then(function() {
    // Set API version to v1.
    gapi.config.update('cloudsearch.config/apiVersion', 'v1');

    // Build the result container and bind to DOM elements.
    var resultsContainer = new gapi.cloudsearch.widget.resultscontainer.Builder()
      .setSearchApplicationId(searchApplicationName)
      .setSearchResultsContainerElement(document.getElementById('search_results'))
      .setFacetResultsContainerElement(document.getElementById('facet_results'))
      .build();

    // Build the search box and bind to DOM elements.
    var searchBox = new gapi.cloudsearch.widget.searchbox.Builder()
      .setSearchApplicationId(searchApplicationName)
      .setInput(document.getElementById('search_input'))
      .setAnchor(document.getElementById('suggestions_anchor'))
      .setResultsContainer(resultsContainer)
      .build();
  }).then(function() {
    // Init API/oauth client w/client ID.
    return gapi.auth2.init({
        'clientId': clientId,
        'scope': 'https://www.googleapis.com/auth/cloud_search.query'
    });
  });
}

Yukarıdaki örnekte, şu şekilde tanımlanan yapılandırma için iki değişkene başvurulur:

serving/widget/public/with_css/app.js
/**
* Client ID from OAuth credentials.
*/
var clientId = "...apps.googleusercontent.com";

/**
* Full resource name of the search application, such as
* "searchapplications/<your-id>".
*/
var searchApplicationName = "searchapplications/...";

Oturum açma deneyimini özelleştirme

Widget varsayılan olarak kullanıcılardan oturum açmalarını ve uygulamayı yetkilendirmelerini ister. ne kadar kısa bir süre olduğunu gösterir. Tekliflerinizi otomatikleştirmek ve optimize etmek için Web Siteleri İçin Google ile Oturum Açma .

Kullanıcıları doğrudan yetkilendirin

Google ile Oturum Aç özelliğini kullanarak oturum açın veya kullanıcıların oturumlarını kapatın. Örneğin, örneğin, isSignedIn oturum açma değişikliklerini takip etmek için GoogleAuth.signIn() kullanılır oturum açma işlemini bir düğmeden başlatma yöntemi tıklayın:

serving/widget/public/with_signin/app.js
// Handle sign-in/sign-out.
let auth = gapi.auth2.getAuthInstance();

// Watch for sign in status changes to update the UI appropriately.
let onSignInChanged = (isSignedIn) => {
  // Update UI to switch between signed in/out states
  // ...
}
auth.isSignedIn.listen(onSignInChanged);
onSignInChanged(auth.isSignedIn.get()); // Trigger with current status.

// Connect sign-in/sign-out buttons.
document.getElementById("sign-in").onclick = function(e) {
  auth.signIn();
};
document.getElementById("sign-out").onclick = function(e) {
  auth.signOut();
};

Daha fazla bilgi için Google ile oturum açma başlıklı makaleyi inceleyin.

Kullanıcıların otomatik olarak oturum açmasını sağlayın

kuruluşunuzdaki kullanıcılar adına kullanmanız gerekir. Bu teknik Cloud Identity Aware Proxy kullanıyorsanız koruyabilirsiniz.

Daha fazla bilgi için Google ile Oturum Açma'yı BT Uygulamalarıyla kullanma başlıklı makaleye göz atın.

Arayüzü özelleştirme

Arama arayüzünün görünümünü bir kombinasyon görebilirsiniz:

  • Stilleri CSS ile geçersiz kılma
  • Öğeleri adaptörle süsleyin
  • Adaptörle özel öğeler oluşturma

Stilleri CSS ile geçersiz kılma

Arama widget'ı, stil önerisi ve sonuç öğelerini oluşturmak için kendi CSS'siyle birlikte gelir ve sayfalara ayırma denetimlerini içerir. Bu öğeleri gerektiği gibi yeniden biçimlendirebilirsiniz.

Arama widget'ı, yükleme sırasında varsayılan stil sayfasını dinamik bir şekilde yükler. Bu durum, uygulama stil sayfaları yüklendikten sonra oluyor ve öncelik artıyor. gözden geçireceğiz. Kendi stillerinizin varsayılan stillere göre öncelikli olmasını sağlamak için varsayılan kuralların kesinliğini artırmak için üst öğe seçicileri kullanın.

Örneğin, aşağıdaki kuralın Dokümanda link veya style etiketi var.

.cloudsearch_suggestion_container {
  font-size: 14px;
}

Bunun yerine, kuralı üst kapsayıcının kimliği veya sınıfıyla niteleyin. beyan edersiniz.

#suggestions_anchor .cloudsearch_suggestion_container {
  font-size: 14px;
}

Widget tarafından oluşturulan destek sınıflarının listesi ve örnek HTML için Desteklenen CSS sınıfları referansı.

Öğeleri adaptörle süsleyin

Bir öğeyi oluşturma işleminden önce süslemek için bir öğe oluşturup yeniden düzenleyin. Aşağıdaki gibi süsleme yöntemlerinden birini uygulayan adaptör: decorateSuggestionElement veya decorateSearchResultElement.

Örneğin, aşağıdaki bağdaştırıcılar öneriye özel bir sınıf ekler ve öğeleri dahil eder.

serving/widget/public/with_decorated_element/app.js
/**
 * Search box adapter that decorates suggestion elements by
 * adding a custom CSS class.
 */
function SearchBoxAdapter() {}
SearchBoxAdapter.prototype.decorateSuggestionElement = function(element) {
  element.classList.add('my-suggestion');
}

/**
 * Results container adapter that decorates suggestion elements by
 * adding a custom CSS class.
 */
function ResultsContainerAdapter() {}
ResultsContainerAdapter.prototype.decorateSearchResultElement = function(element) {
  element.classList.add('my-result');
}

Widget'ı başlatırken adaptörü kaydetmek için setAdapter() ilgili Builder sınıfının yöntemini değiştirin:

serving/widget/public/with_decorated_element/app.js
// Build the result container and bind to DOM elements.
var resultsContainer = new gapi.cloudsearch.widget.resultscontainer.Builder()
  .setAdapter(new ResultsContainerAdapter())
  // ...
  .build();

// Build the search box and bind to DOM elements.
var searchBox = new gapi.cloudsearch.widget.searchbox.Builder()
  .setAdapter(new SearchBoxAdapter())
  // ...
  .build();

Dekoratörler, kapsayıcı öğenin özelliklerini değiştirebileceği gibi, alt öğelere karşılık gelir. Dekorasyon sırasında alt öğeler eklenebilir veya kaldırılabilir. Ancak öğelerde yapısal değişiklikler yapıyorsanız, doğrudan süslemeyi tercih edebilir.

Adaptörle özel öğeler oluşturma

Bir öneri, özellik kapsayıcı veya arama sonucu için özel öğe oluşturmak isterseniz: kullanan bir bağdaştırıcı oluşturup kaydedin createSuggestionElement createFacetResultElement, veya createSearchResultElement özümsemesini sağlamalısınız.

Aşağıdaki bağdaştırıcılar, özel öneri ve arama sonuçları oluşturmayı gösterir öğeleri için HTML <template> etiketleri kullanır.

serving/widget/public/with_custom_element/app.js
/**
 * Search box adapter that overrides creation of suggestion elements.
 */
function SearchBoxAdapter() {}
SearchBoxAdapter.prototype.createSuggestionElement = function(suggestion) {
  let template = document.querySelector('#suggestion_template');
  let fragment = document.importNode(template.content, true);
  fragment.querySelector('.suggested_query').textContent = suggestion.suggestedQuery;
  return fragment.firstElementChild;
}

/**
 * Results container adapter that overrides creation of result elements.
 */
function ResultsContainerAdapter() {}
ResultsContainerAdapter.prototype.createSearchResultElement = function(result) {
  let template = document.querySelector('#result_template');
  let fragment = document.importNode(template.content, true);
  fragment.querySelector('.title').textContent = result.title;
  fragment.querySelector('.title').href = result.url;
  let snippetText = result.snippet != null ?
    result.snippet.snippet : '';
  fragment.querySelector('.query_snippet').innerHTML = snippetText;
  return fragment.firstElementChild;
}

Widget'ı başlatırken bağdaştırıcıyı kaydetmek için setAdapter() ilgili Builder sınıfının yöntemini kullanın:

serving/widget/public/with_custom_element/app.js
// Build the result container and bind to DOM elements.
var resultsContainer = new gapi.cloudsearch.widget.resultscontainer.Builder()
  .setAdapter(new ResultsContainerAdapter())
  // ...
  .build();

// Build the search box and bind to DOM elements.
var searchBox = new gapi.cloudsearch.widget.searchbox.Builder()
  .setAdapter(new SearchBoxAdapter())
  // ...
  .build();

createFacetResultElement ile özel özellik öğeleri oluşturma çeşitli kısıtlamalara tabidir:

  • cloudsearch_facet_bucket_clickable CSS sınıfını şuraya eklemelisiniz: öğe kullanıcılarının bir paketi açmak/kapatmak için tıkladığı öğe.
  • Her paketi CSS ile içeren bir öğe içine sarmalamanız gerekir cloudsearch_facet_bucket_container sınıfı.
  • Paketleri şurada göründüklerinden farklı bir sırada oluşturamazsınız: tıklayın.

Örneğin, aşağıdaki snippet, bunun yerine bağlantılar kullanarak façetalar oluşturur onay kutusu işaretini kaldırın.

serving/widget/public/with_custom_facet/app.js
/**
 * Results container adapter that intercepts requests to dynamically
 * change which sources are enabled based on user selection.
 */
function ResultsContainerAdapter() {
  this.selectedSource = null;
}

ResultsContainerAdapter.prototype.createFacetResultElement = function(result) {
  // container for the facet
  var container = document.createElement('div');

  // Add a label describing the facet (operator/property)
  var label = document.createElement('div')
  label.classList.add('facet_label');
  label.textContent = result.operatorName;
  container.appendChild(label);

  // Add each bucket
  for(var i in result.buckets) {
    var bucket = document.createElement('div');
    bucket.classList.add('cloudsearch_facet_bucket_container');

    // Extract & render value from structured value
    // Note: implementation of renderValue() not shown
    var bucketValue = this.renderValue(result.buckets[i].value)
    var link = document.createElement('a');
    link.classList.add('cloudsearch_facet_bucket_clickable');
    link.textContent = bucketValue;
    bucket.appendChild(link);
    container.appendChild(bucket);
  }
  return container;
}

// Renders a value for user display
ResultsContainerAdapter.prototype.renderValue = function(value) {
  // ...
}

Arama davranışını özelleştirin

Arama uygulaması ayarları, varsayılan değeri temsil eder statiktir. Dinamik arama ağı reklamlarını uygulamak için filtreleri veya özellikleri (ör. kullanıcıların veri kaynakları arasında geçiş yapmalarına izin verme) arama isteğine müdahale ederek arama uygulaması ayarlarını geçersiz kılma bunu kullanabilirsiniz.

Adaptör interceptSearchRequest isteklerinde değişiklik yapılmasını önlemek için search API göz önünde bulundurmalısınız.

Örneğin, aşağıdaki bağdaştırıcı, sorguları kısıtlama isteklerine müdahale eder kullanıcı tarafından seçilen kaynağa

serving/widget/public/with_request_interceptor/app.js
/**
 * Results container adapter that intercepts requests to dynamically
 * change which sources are enabled based on user selection.
 */
function ResultsContainerAdapter() {
  this.selectedSource = null;
}
ResultsContainerAdapter.prototype.interceptSearchRequest = function(request) {
  if (!this.selectedSource || this.selectedSource == 'ALL') {
    // Everything selected, fall back to sources defined in the search
    // application.
    request.dataSourceRestrictions = null;
  } else {
    // Restrict to a single selected source.
    request.dataSourceRestrictions = [
      {
        source: {
          predefinedSource: this.selectedSource
        }
      }
    ];
  }
  return request;
}

Widget'ı başlatırken bağdaştırıcıyı kaydetmek için setAdapter() ResultsContainer oluştururken

serving/widget/public/with_request_interceptor/app.js
var resultsContainerAdapter = new ResultsContainerAdapter();
// Build the result container and bind to DOM elements.
var resultsContainer = new gapi.cloudsearch.widget.resultscontainer.Builder()
  .setAdapter(resultsContainerAdapter)
  // ...
  .build();

Aşağıdaki HTML, şuna göre filtreleme için bir seçim kutusu görüntülemek üzere kullanılır: kaynaklar:

serving/widget/public/with_request_interceptor/index.html
<div>
  <span>Source</span>
  <select id="sources">
    <option value="ALL">All</option>
    <option value="GOOGLE_GMAIL">Gmail</option>
    <option value="GOOGLE_DRIVE">Drive</option>
    <option value="GOOGLE_SITES">Sites</option>
    <option value="GOOGLE_GROUPS">Groups</option>
    <option value="GOOGLE_CALENDAR">Calendar</option>
    <option value="GOOGLE_KEEP">Keep</option>
  </select>
</div>

Aşağıdaki kod değişikliği izler, seçimi ayarlar ve Gerekirse sorguyu yeniden yürütür.

serving/widget/public/with_request_interceptor/app.js
// Handle source selection
document.getElementById('sources').onchange = (e) => {
  resultsContainerAdapter.selectedSource = e.target.value;
  let request = resultsContainer.getCurrentRequest();
  if (request.query) {
    // Re-execute if there's a valid query. The source selection
    // will be applied in the interceptor.
    resultsContainer.resetState();
    resultsContainer.executeRequest(request);
  }
}

Ayrıca, RACI matrisinde interceptSearchResponse girin.

API sürümünü sabitleyin

Widget varsayılan olarak API'nin en son kararlı sürümünü kullanır. Bir belirli bir sürüm için cloudsearch.config/apiVersion yapılandırma parametresini ayarlayın tercih ettiğiniz sürüme güncelleyin.

serving/widget/public/basic/app.js
gapi.config.update('cloudsearch.config/apiVersion', 'v1');

Ayarlanmadan bırakılırsa veya geçersiz bir değere ayarlanırsa API sürümü varsayılan olarak 1.0 olur.

Widget sürümünü sabitleme

Arama arayüzlerinde beklenmedik değişiklikler önlemek için, Gösterilen cloudsearch.config/clientVersion yapılandırma parametresi:

gapi.config.update('cloudsearch.config/clientVersion', 1.1);

Ayarlanmadan bırakılırsa veya geçersiz bir değere ayarlanırsa widget sürümü varsayılan olarak 1.0 olur.

Arama arayüzünün güvenliğini sağlayın

Arama sonuçları son derece hassas bilgiler içeriyor. En iyi uygulamaları takip edin güvenlik önlemlerinden oluşan tıklama korsanlığı saldırılarıdır.

Daha fazla bilgi için OWASP Rehber Projesi'ne bakın.

Hata ayıklamayı etkinleştir

interceptSearchRequest kullanın seçeneğini tıklayın. Örneğin:

  if (!request.requestOptions) {
  // Make sure requestOptions is populated
  request.requestOptions = {};
  }
  // Enable debugging
  request.requestOptions.debugOptions = {enableDebugging: true}

  return request;