2016-07-07 360 views
0

我已經把靜態視圖和模型視圖放在Django生成的sitemap.xml文件中,但我不知道如何告訴Django將所有媒體文件放入它中?我有一百個帶有seo友好鏈接的PDF文件,我希望它們位於我的sitemap.xml中,但是因爲它們與我的任何模型都不相關,所以我不知道如何管理它?如何告訴Django將sitemap.xml中的媒體(pdf)文件URL?

編輯︰我幾乎忘了一件重要的事情 - 我的媒體(pdf)文件通過CloudFront服務,所以即使我管理某種方式列出他們在我的Django Sitemap.xml我會有更多的問題,因爲他們有'的東西。 cloudfront.com'在他們的網址,而不是在我的網站的網址'example.com'。 這甚至有可能解決?這如何反映在搜索引擎優化?

求助: @kb,謝謝你的一個很好的答案!正如你在答案的第一部分中所建議的那樣,我在我的htaccess中使用了RewriteRule,並且它工作正常。 作爲第二部分的,而不是爲我的媒體文件創建模型(這會工作得很好,但唯一不足的是人工添加的每個新的PDF文件) 我決定將一些行添加到我的項目()方法,這樣我就可以列出桶內容和過濾PDF文件。隨着我可以有我所有的文件跟上時代的一切的時候,很容易:

#sitemap.py 
import boto 
from boto.s3.key import Key 
from boto.s3.connection import S3Connection 
import re 

def items(self):  
     AWS_ACCESS_KEY_ID = #'my_access_key_number' 
     AWS_SECRET_ACCESS_KEY = #'my_secret_access_key' 
     Bucketname = #'my_bucket_name' 
     conn = boto.s3.connect_to_region('eu-central-1', aws_access_key_id=AWS_ACCESS_KEY_ID, aws_secret_access_key=AWS_SECRET_ACCESS_KEY, is_secure=False, calling_format = boto.s3.connection.OrdinaryCallingFormat()) 
     bucket = conn.get_bucket(Bucketname) 
     new_list = [] 
     regex = re.compile(r'bucketsubfolder/media.*\.pdf$', re.I) #i hold my media files in bucketsubfolder so url is for example somedomain.cloudfront.net/bucketsubfolder/media/somefile.pdf 
     for item in bucket.list(): 
      if regex.match(item.name): 
       new_list.append(item.name) 
     return new_list 
+0

您不允許在站點地圖中使用外部URL(或者說,它們不會產生所需的效果)。我認爲你最好的選擇是在你的網站上創建一個類似'/ hosted/pdf/xxxx.pdf'的路徑,使用重寫/位置模式重定向到'cloudfront.com/pdf/xxxx.pdf'或類似的路徑。這樣,您可以在站點地圖中使用站點URL,但仍然可以直接將瀏覽器發送到雲端服務內容。 –

+0

好吧,我認爲這可以幫助解決1/2的問題。你有什麼想法如何以編程方式在django站點地圖中包含PDF? –

+0

恐怕我已經很長時間沒有做過Django了,但是基本上應該在Sitemap類中有一個'items()'來返回內容,所以你想在返回之前手動添加東西到列表中。我認爲你可以像在https://docs.djangoproject.com/en/1.9/ref/contrib/sitemaps/中顯示的內容一樣,通過像'BlogSitemap'類一樣擴展'Sitemap'來做類似的事情。 (也請查看標題#sitemap-for-static-views。) –

回答

1

你不允許您的站點地圖使用外部URL(或者更確切地說,他們不會收到預期的效果被Google收錄爲網站內容的一部分)。

我認爲您最好的選擇是在您的網站上專門設置一個路徑,例如/hosted/pdf/xxxx.pdf,使用mod_rewrite /位置模式/正則表達式將所有內容重寫爲cloudfront.com/pdf/xxxx.pdf或類似內容。

您可以使用您站點地圖中的本地網站的網址,但仍然有發送到CloudFront的瀏覽器直接提供的內容這樣的話,我覺得這甚至可能是一個很好用的302 HTTP狀態代碼。

Sitemap類中,有一個items()方法返回要包含在sitemap.xml中的內容,並且您可以創建自己的類來擴展它並添加其他數據。

您可以手動添加的方法硬編碼的數據,但我認爲,最佳的選擇是創建一個代表每個遠程託管文件模式和包含必要在網站地圖輸出它的信息。 (這也可以讓你添加屬性,如每個文件的基礎上的可見性,並讓你通過管理,假設你爲它設置了一個ModelAdmin。)

我想你可能可以做些類似於他們在http://docs.djangoproject.com/en/1.9/ref/contrib/sitemaps與延伸SitemapBlogSitemap類。請務必在該頁面上查看標題「靜態視圖的站點地圖」。

我的建議是,你選擇的模型方法來表示文件,所以你有你的託管PDF文件(或者其他CDN內容)一個名爲StaticHostedFile或類似的模型,你通過他們都在items()部分重複。它確實要求您爲所有當前的PDF索引創建模型,並在添加新PDF時創建新模型(但可以自動完成)。

可以很高興地知道,您可以在sitemap.xml中添加「includes」,以便您可以將網站內容拆分爲兩個站點地圖(content + pdf),並將它們都包含在站點地圖中。XML,例如:

<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> 
    <sitemap> 
     <loc>http://www.example.com/original_sitemap.xml</loc> 
     <lastmod>2016-07-12T09:12Z</lastmod> 
    </sitemap> 
    <sitemap> 
     <loc>http://www.example.com/pdf_sitemap.xml</loc> 
     <lastmod>2016-07-15T08:55Z</lastmod> 
    </sitemap> 
</sitemapindex> 

這仍然需要本地URL改寫按上述,雖然,但它可以爲當你有幾個獨立的站點地圖結合了一個漂亮的把戲。 (例如,如果在一個子目錄下運行一個Django站點並在另一個子域下運行一個Wordpress站點或者其他內容)。